Ekstraktor podłańcuchów z określonymi słowami kluczowymi
Wyzwanie
Celem tego wyzwania jest stworzenie funkcji, która pobiera ciąg wejściowy, słowo kluczowe start i słowo kluczowe end. Wyodrębniony wynik wyjściowy pochodzi z (ale wykluczony) podanego słowa kluczowego start do (ale wykluczonego) słowa kluczowego end. Podłańcuch wyjściowy podlega poniższym regułom.
We wszystkich przypadkach początkowe / końcowe spacje w wyjściowym podłańcuchu powinny zostać usunięte.
Jeśli dane słowo kluczowe start jest pustym ciągiem, oznacza to, że kotwica znajduje się na początku ciągu wejściowego. W przeciwnym razie pierwszym wystąpieniem danego słowa kluczowego start jest kotwica startowa. Jeśli nie ma żadnego wystąpienia podanego słowa kluczowego start, wynikiem jest pusty ciąg.
Jeśli dane słowo kluczowe end jest pustym ciągiem, oznacza to, że kotwica znajduje się na końcu ciągu wejściowego. W przeciwnym razie pierwszym wystąpieniem danego słowa kluczowego end jest kotwica końca. Jeśli nie ma żadnego wystąpienia podanego słowa kluczowego end, wynikiem jest pusty ciąg.
Jeśli lokalizacja start anchor jest późniejsza niż lokalizacja end anchor lub część pierwszego wystąpienia danego słowa kluczowego start i część pierwszego wystąpienia danego słowa kluczowego end nakładają się, wynikiem jest pusty ciąg.
Podobnie, ale różni się od Wyodrębnij ciąg z danego ciągu , podane kotwice początkowe i końcowe to wiele znaków.
Oto implementacja referencyjna ungolfed w C #
private static string GetTargetString(string stringInput, string startKeywordInput, string endKeywordInput)
{
int startIndex;
if (String.IsNullOrEmpty(startKeywordInput))
{
startIndex = 0;
}
else
{
if (stringInput.IndexOf(startKeywordInput) >= 0)
{
startIndex = stringInput.IndexOf(startKeywordInput) + startKeywordInput.Length;
}
else
{
return "";
}
}
int endIndex;
if (String.IsNullOrEmpty(endKeywordInput))
{
endIndex = stringInput.Length;
}
else
{
if (stringInput.IndexOf(endKeywordInput) > startIndex)
{
endIndex = stringInput.IndexOf(endKeywordInput);
}
else
{
return "";
}
}
// Check startIndex and endIndex
if (startIndex < 0 || endIndex < 0 || startIndex >= endIndex)
{
return "";
}
if (endIndex.Equals(0).Equals(true))
{
endIndex = stringInput.Length;
}
int TargetStringLength = endIndex - startIndex;
return stringInput.Substring(startIndex, TargetStringLength).Trim();
}
Przykładowe dane wejściowe i wyjściowe
Przykładowe dane wejściowe i wyjściowe są wymienione poniżej.
Ciąg wejściowy | Rozpocznij słowo kluczowe | Koniec słowa kluczowego | Wynik |
---|---|---|---|
„C # został opracowany około 2000 roku przez firmę Microsoft w ramach inicjatywy .NET” | ""(pusta struna) | ""(pusta struna) | „C # został opracowany około 2000 roku przez firmę Microsoft w ramach inicjatywy .NET” |
„C # został opracowany około 2000 roku przez firmę Microsoft w ramach inicjatywy .NET” | ""(pusta struna) | ".NETTO" | „C # został opracowany około 2000 roku przez firmę Microsoft jako część jego” |
„C # został opracowany około 2000 roku przez firmę Microsoft w ramach inicjatywy .NET” | "DO#" | ""(pusta struna) | „został opracowany około 2000 roku przez firmę Microsoft w ramach inicjatywy .NET” |
„C # został opracowany około 2000 roku przez firmę Microsoft w ramach inicjatywy .NET” | "DO#" | ".NETTO" | "został opracowany około 2000 r. przez firmę Microsoft jako część jego" |
„C # został opracowany około 2000 roku przez firmę Microsoft w ramach inicjatywy .NET” | ".NETTO" | ""(pusta struna) | "inicjatywa" |
„C # został opracowany około 2000 roku przez firmę Microsoft w ramach inicjatywy .NET” | ""(pusta struna) | "DO#" | ""(pusta struna) |
„C # został opracowany około 2000 roku przez firmę Microsoft w ramach inicjatywy .NET” | ".NETTO" | "DO#" | ""(pusta struna) |
„C # został opracowany około 2000 roku przez firmę Microsoft w ramach inicjatywy .NET” | "ABC" | "DO#" | ""(pusta struna) |
„C # został opracowany około 2000 roku przez firmę Microsoft w ramach inicjatywy .NET” | ".NETTO" | „XYZ” | ""(pusta struna) |
„C # został opracowany około 2000 roku przez firmę Microsoft w ramach inicjatywy .NET” | "ABC" | „XYZ” | ""(pusta struna) |
Zasady
To jest code-golf . Wygrywa odpowiedź z najmniejszą liczbą bajtów.
Odpowiedzi
APL (Dyalog Extended) , 24 bajty ( SBCS )
Pełny program, który monituje o podanie tablicy [EndKeyword,StartKeyword,InputString]
. Wymaga indeksowania opartego na 0.
⌂deb⊃(⌽⊢↓⍨1⍳⍨⊣,⍷)/⌽¨@0⊢⎕
Wypróbuj online!
⎕
monit o wprowadzenie danych
⊢
Na tym…
⌽¨@0
odwróć wszystkie elementy, które występują przy przesunięciu 0
(
… )/
Zmniejszyć od prawej strony, używając następującej milczącej funkcji:
⍷
wskaż listą logiczną wszystkie miejsca, w których lewy argument zaczyna się w prawym
⊣,
dołącz do tego lewy argument
1⍳⍨
znajdź przesunięcie pierwszego 1
⊢↓⍨
usuń tyle wiodących elementów z właściwego argumentu
⌽
odwróć (następnym razem zrób to od końca, a potem przywróć kolejność)
⊃
ujawniają obudowę spowodowaną redukcją macierzy jednowymiarowej do macierzy 0-wymiarowej
⌂deb
d elete e nding ( początkowe i końcowe) b lanks
JavaScript (ES6), 80 75 bajtów
Zawiera kilka niedrukowalnych znaków, które są wymienione poniżej.
(s,a,b)=>s.replace(b||/$/,"").replace(a,"").match(/ *(.*?) *|$/)[1]||""
Wypróbuj online!
Skomentowano
(s, a, b) => // s = input string, a = start keyword, b = end keyword
s.replace( // replace in s:
b || /$/, // look for the end keyword, or the regex /$/ if it's empty
"\3" // and replace it with ETX (end of text)
) //
.replace( // replace in the resulting string:
a, // look for the start keyword
"\2" // and replace it with STX (start of text)
) //
.match( // attempt to match:
/\2 *(.*?) *\3|$/ // "\2" STX ) // " *" followed by optional whitespace // "(.*?)" followed by a non-greedy string (the payload) // " *" followed by optional whitespace // "\3" followed by ETX // "|$" OR match an empty string to make sure that
// match() doesn't return null
[1] || "" // return the payload string, or an empty string if undefined
Python 3 , 86 77 75 bajtów
Zapisano 9 bajtów dzięki movatica !!!
Zapisano 2 bajty dzięki OVS !!!
lambda s,a,b:s[s.find(a):(b in s)*s.find(b)if b else None][len(a):].strip()
Wypróbuj online!
JavaScript (Node.js) , 74 bajty
(s,a,b)=>s.substr(p=(s+a).indexOf(a)+a.length,b?s.indexOf(b)-p:1/0).trim()
Wypróbuj online!
Całkiem proste...
Ruby , 66 bajtów
->w,s,e,r=Regexp{"#{w[/#{r.quote s}\K.+(?=#{r.quote e})/]}".strip}
Wypróbuj online!
Inna metoda bez użycia wyrażenia regularnego,
Ruby , 72 bajty
->w,s,e{"#{w[((w+s).index(s)+s.size rescue 0)...w.rindex(e)||0]}".strip}
Wypróbuj online!
Python 3 , 100 85 bajtów
Wersja Regex, nadal nie może pokonać algorytmu wycinania .
from re import*
r=escape
f=lambda s,b,e:(search(r(b)+'(.+)'+r(e),s)or' ')[1].strip()
Wypróbuj online!
Retina 0.8.2 , 60 bajtów
(.*)¶(.+)?¶.*?\1 *(.*?) *(?<!(?=\2).*)(?(2)\2.*|$)|(.|¶)+ $3
Wypróbuj online! Pobiera dane wejściowe jako początek, koniec, ciąg w oddzielnych wierszach, ale łącze służy do testowania zestawu z nagłówkiem, który dla wygody konwertuje z ciągu oddzielonego przecinkami, końca, początku. Wyjaśnienie:
(.*)¶
Dopasuj słowo kluczowe start.
(.+)?¶
Opcjonalnie dopasuj niepuste słowo kluczowe końca.
.*?\1
Znajdź słowo kluczowe start tak wcześnie, jak to możliwe w ciągu, plus opcjonalne spacje.
*(.*?) *
Dopasuj tak krótki wynik, jak to możliwe (tak, aby słowo kluczowe end zostało znalezione jak najwcześniej w ciągu), ale także przytnij spacje wokół niego.
(?<!(?=\2).*)
Upewnij się, że słowo kluczowe end nie zostało już przekazane w tym momencie.
(?(2)\2.*|$)
Jeśli słowo kluczowe end było puste, dopasuj tylko na końcu ciągu, w przeciwnym razie dopasuj słowo kluczowe end i resztę ciągu.
|(.|¶)+
Jeśli nie można było niczego dopasować, usuń wszystko.
$3
Zachowaj pożądany efekt.
Język Wolfram (Mathematica) , 93 bajty
sStringTrim@StringTake[s,i=1;If[i*=-1;#=="",0,StringPosition[s,#][[1,i]]]-i&/@#]/._@_:>""&
Wypróbuj online!
Czerwony , 90 bajtów
func[t s e][p:""if""<> s[append s" "]if e =""[e:[end]]parse t[thru s copy p to[opt" "e]]p]
Wypróbuj online!
C (gcc) , 168 152 143 132 112 bajtów
Ogromne -38 dzięki @ceilingcat
#define r strstr(c
*f(c,s,e)int*c,*s,*e;{return*e&&r,s)>r,e)|!r,s)|!r,e)||*e&&(*r,e)=0)?"":r,s)+strlen(s)+!!*s;}
Wypróbuj online!
JavaScript (ES6) 95 92 bajty, bez regex!
(i,s,e,t=i.indexOf(s),r=i.lastIndexOf(e))=>t!=-1&r!=-1?(i.substring(t+s.length,r)).trim():''
Jak to wypróbować:
Otwórz konsolę JavaScript przeglądarki i wklej następujące elementy.
((i,s,e,t=i.indexOf(s),r=i.lastIndexOf(e))=>t!=-1&r!=-1?(i.substring(t+s.length,r)).trim():'')('C# was developed around 2000 by Microsoft as part of its .NET initiative', 'C#', '.NET')
Węgiel , 41 bajtów
≔⎇ζ…θ⌕θζθθ≔⎇η⪫Φ⪪θηκηθθ≔⌕AEθ›ι ¹ε¿ε✂θ⌊ε⊕⌈ε
Wypróbuj online! Link prowadzi do pełnej wersji kodu. Uważaj, aby wprowadzić wystarczającą liczbę znaków nowej linii, nawet jeśli jedno ze słów kluczowych jest puste. Wyjaśnienie:
≔⎇ζ…θ⌕θζθθ
Jeśli słowo kluczowe end nie jest puste, obetnij ciąg przy jego pierwszym pojawieniu się. (Na szczęście CycleChop
skraca ciąg do opróżnienia, jeśli jego dane wejściowe są ujemne).
≔⎇η⪫Φ⪪θηκηθθ
Jeśli słowo kluczowe start nie jest puste, podziel łańcuch na słowo kluczowe, odrzuć pierwszy element i ponownie połącz łańcuch. Powoduje to powstanie pustego ciągu, jeśli słowo kluczowe start nie występuje w ciągu.
≔⌕AEθ›ι ¹ε
Sprawdź, czy ciąg nie zawiera spacji.
¿ε✂θ⌊ε⊕⌈ε
Jeśli tak, to drukuj od pierwszej do ostatniej bez spacji.
R , 111 bajtów
function(s,a,b,c=?s,`?`=nchar,r=regexpr)trimws(substr(s,`if`((d=r(a,s,f=T))>0,d+?a,c),`if`(?b,r(b,s,f=T)-1,c)))
Wypróbuj online!
Proste podejście: Znaleziska ograniczające używając słów regexpr
(z argumentem f
ixed = T
rue aby upewnić się, że łańcuch tekstowy nie jest interpretowany jako regex), dostaje substr
ing między nimi, a następnie trim
s w
hite s
tempo z obu końców.
Ponieważ funkcje nchar
i regexpr
są używane dwukrotnie, krótsze jest definiowanie jednoznakowych aliasów. W przypadku programu nchar
możemy nawet przedefiniować operator jednoargumentowy ?
jako jego alias, dzięki czemu unikniemy potrzeby stosowania nawiasów. Niestety ta sztuczka nie jest tutaj możliwa ze regexpr
względu na konieczność f
podania mu dodatkowego argumentu ixed = T
rue.
C # 114 bajtów
(i,s,e)=>{int p=(i+(s??="")).IndexOf(s)+s.Length,q=$"{e}"==""?i.Length:i.IndexOf(e);return p<q?i[p..q].Trim():"";}