Ekstraktor podłańcuchów z określonymi słowami kluczowymi

Jan 07 2021

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

2 Adám Jan 07 2021 at 15:32

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

⌂debd elete e nding ( początkowe i końcowe) b lanks

5 Arnauld Jan 07 2021 at 11:31

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
3 Noodle9 Jan 08 2021 at 19:19

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!

1 tsh Jan 07 2021 at 13:12

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...

1 vrintle Jan 07 2021 at 11:57

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!

1 movatica Jan 08 2021 at 19:47

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!

1 Neil Jan 09 2021 at 19:04

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.

1 att Jan 07 2021 at 13:42

Język Wolfram (Mathematica) , 93 bajty

sStringTrim@StringTake[s,i=1;If[i*=-1;#=="",0,StringPosition[s,#][[1,i]]]-i&/@#]/._@_:>""&

Wypróbuj online!

1 GalenIvanov Jan 07 2021 at 15:30

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!

1 Davide Jan 10 2021 at 22:26

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!

myjobistobehappy Jan 07 2021 at 13:05

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')
Neil Jan 09 2021 at 22:40

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 CycleChopskraca 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.

DominicvanEssen Jan 11 2021 at 06:31

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 fixed = True aby upewnić się, że łańcuch tekstowy nie jest interpretowany jako regex), dostaje substring między nimi, a następnie trims white stempo z obu końców.

Ponieważ funkcje nchari regexprsą używane dwukrotnie, krótsze jest definiowanie jednoznakowych aliasów. W przypadku programu ncharmoż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 regexprwzględu na konieczność fpodania mu dodatkowego argumentu ixed = True.

pinkfloydx33 Jan 24 2021 at 20:05

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():"";}