Estrattore di sottostringa con parole chiave specifiche

Jan 07 2021

Sfida

L'obiettivo di questa sfida è creare una funzione che accetti una stringa di input, una parola chiave iniziale e una parola chiave finale. Il risultato dell'output estratto proviene (ma escluso) dalla parola chiave iniziale data alla parola chiave end (ma esclusa). La sottostringa di output segue le regole come di seguito.

  • In tutti i casi, gli spazi iniziali / finali nella sottostringa di output dovrebbero essere rimossi.

  • Se la parola chiave di inizio data è una stringa vuota, significa che l'ancora si trova all'inizio della stringa di input. Altrimenti, la prima occorrenza della parola chiave di inizio data è un'ancora di inizio. Se non è presente alcuna occorrenza della parola chiave iniziale specificata, l'output è una stringa vuota.

  • Se la parola chiave end specificata è una stringa vuota, significa che l'ancora si trova alla fine della stringa di input. Altrimenti, la prima occorrenza della parola chiave end specificata è un'ancora di fine. Se non è presente alcuna occorrenza della parola chiave end specificata, l'output è una stringa vuota.

  • Se la posizione dell'ancoraggio iniziale è successiva alla posizione dell'ancoraggio finale, o una parte della prima occorrenza della parola chiave iniziale data e una parte della prima occorrenza della parola chiave finale specificata sono sovrapposte, l'output è una stringa vuota.

Simile ma diverso da Estrai una stringa da una determinata stringa , le ancore di inizio e fine fornite sono più caratteri.

Ecco un'implementazione di riferimento ungolfed in 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();
}

Input e output di esempio

L'input e l'output di esempio sono elencati di seguito.

Stringa di input Avvia parola chiave Fine parola chiave Produzione
"C # è stato sviluppato intorno al 2000 da Microsoft come parte della sua iniziativa .NET" ""(stringa vuota) ""(stringa vuota) "C # è stato sviluppato intorno al 2000 da Microsoft come parte della sua iniziativa .NET"
"C # è stato sviluppato intorno al 2000 da Microsoft come parte della sua iniziativa .NET" ""(stringa vuota) ".NETTO" "C # è stato sviluppato intorno al 2000 da Microsoft come parte del suo"
"C # è stato sviluppato intorno al 2000 da Microsoft come parte della sua iniziativa .NET" "C #" ""(stringa vuota) "è stato sviluppato intorno al 2000 da Microsoft come parte della sua iniziativa .NET"
"C # è stato sviluppato intorno al 2000 da Microsoft come parte della sua iniziativa .NET" "C #" ".NETTO" "è stato sviluppato intorno al 2000 da Microsoft come parte del suo"
"C # è stato sviluppato intorno al 2000 da Microsoft come parte della sua iniziativa .NET" ".NETTO" ""(stringa vuota) "iniziativa"
"C # è stato sviluppato intorno al 2000 da Microsoft come parte della sua iniziativa .NET" ""(stringa vuota) "C #" ""(stringa vuota)
"C # è stato sviluppato intorno al 2000 da Microsoft come parte della sua iniziativa .NET" ".NETTO" "C #" ""(stringa vuota)
"C # è stato sviluppato intorno al 2000 da Microsoft come parte della sua iniziativa .NET" "ABC" "C #" ""(stringa vuota)
"C # è stato sviluppato intorno al 2000 da Microsoft come parte della sua iniziativa .NET" ".NETTO" "XYZ" ""(stringa vuota)
"C # è stato sviluppato intorno al 2000 da Microsoft come parte della sua iniziativa .NET" "ABC" "XYZ" ""(stringa vuota)

Regole

Questo è il golf in codice . La risposta con il minor numero di byte vince.

Risposte

2 Adám Jan 07 2021 at 15:32

APL (Dyalog Extended) , 24 byte ( SBCS )

Programma completo che richiede un array di file [EndKeyword,StartKeyword,InputString]. Richiede un'indicizzazione basata su 0.

⌂deb⊃(⌽⊢↓⍨1⍳⍨⊣,⍷)/⌽¨@0⊢⎕

Provalo online!

 richiesta di input

 su quello…

⌽¨@0 inverte tutti gli elementi che si verificano all'offset 0

(... )/ ridurre da destra utilizzando la seguente funzione tacita:

 indicare con un elenco booleano tutti i punti in cui l'argomento di sinistra inizia nell'argomento di destra

⊣, anteponi l'argomento a sinistra a quello

1⍳⍨ trova l'offset del primo 1

⊢↓⍨ lascia cadere tanti elementi principali dall'argomento giusto

inverso (la prossima volta, fallo dalla fine e dopo, ripristina l'ordine)

 divulgare l'involucro causato dalla riduzione da una matrice unidimensionale a una matrice 0-dimensionale

⌂debd elete e reperto (iniziali e finali) b Lanks

5 Arnauld Jan 07 2021 at 11:31

JavaScript (ES6),  80  75 byte

Questo contiene alcuni caratteri non stampabili di cui sotto.

(s,a,b)=>s.replace(b||/$/,"").replace(a,"").match(/ *(.*?) *|$/)[1]||""

Provalo online!

Commentato

(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 byte

Salvati 9 byte grazie a movatica !!!
Salvato 2 byte grazie a ovs !!!

lambda s,a,b:s[s.find(a):(b in s)*s.find(b)if b else None][len(a):].strip()

Provalo online!

1 tsh Jan 07 2021 at 13:12

JavaScript (Node.js) , 74 byte

(s,a,b)=>s.substr(p=(s+a).indexOf(a)+a.length,b?s.indexOf(b)-p:1/0).trim()

Provalo online!

Abbastanza semplice ...

1 vrintle Jan 07 2021 at 11:57

Ruby , 66 byte

->w,s,e,r=Regexp{"#{w[/#{r.quote s}\K.+(?=#{r.quote e})/]}".strip}

Provalo online!

Un altro metodo senza l'uso di regex,

Ruby , 72 byte

->w,s,e{"#{w[((w+s).index(s)+s.size rescue 0)...w.rindex(e)||0]}".strip}

Provalo online!

1 movatica Jan 08 2021 at 19:47

Python 3 , 100 85 byte

Versione Regex, ancora non può battere l' algoritmo di slicing .

from re import*
r=escape
f=lambda s,b,e:(search(r(b)+'(.+)'+r(e),s)or'  ')[1].strip()

Provalo online!

1 Neil Jan 09 2021 at 19:04

Retina 0.8.2 , 60 byte

(.*)¶(.+)?¶.*?\1 *(.*?) *(?<!(?=\2).*)(?(2)\2.*|$)|(.|¶)+ $3

Provalo online! Accetta l'input come inizio, fine, stringa su righe separate ma il collegamento è alla suite di test con intestazione che converte da stringa separata da virgola, fine, inizio per comodità. Spiegazione:

(.*)¶

Trova la parola chiave iniziale.

(.+)?¶

Facoltativamente, abbina una parola chiave finale non vuota.

.*?\1

Trova la parola chiave iniziale il prima possibile nella stringa, più gli spazi facoltativi.

 *(.*?) *

Trova il risultato il più breve possibile (in modo che la parola chiave end venga trovata il prima possibile nella stringa) ma ritaglia anche gli spazi attorno ad essa.

(?<!(?=\2).*)

Assicurati che la parola chiave end non sia già stata passata a questo punto.

(?(2)\2.*|$)

Se la parola chiave end era vuota, corrisponde solo alla fine della stringa, altrimenti corrisponde alla parola chiave end e al resto della stringa.

|(.|¶)+

Se non è stato possibile trovare una corrispondenza, elimina tutto.

$3

Mantieni il risultato desiderato.

1 att Jan 07 2021 at 13:42

Wolfram Language (Mathematica) , 93 byte

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

Provalo online!

1 GalenIvanov Jan 07 2021 at 15:30

Rosso , 90 byte

func[t s e][p:""if""<> s[append s" "]if e =""[e:[end]]parse t[thru s copy p to[opt" "e]]p]

Provalo online!

1 Davide Jan 10 2021 at 22:26

C (gcc) , 168 152 143 132 112 byte

Un enorme -38 grazie a @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;}

Provalo online!

myjobistobehappy Jan 07 2021 at 13:05

JavaScript (ES6) 95 92 byte, nessuna espressione regolare!

(i,s,e,t=i.indexOf(s),r=i.lastIndexOf(e))=>t!=-1&r!=-1?(i.substring(t+s.length,r)).trim():''

Come provarlo:

Apri la console JavaScript del tuo browser e incolla quanto segue.

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

Carboncino , 41 byte

≔⎇ζ…θ⌕θζθθ≔⎇η⪫Φ⪪θηκηθθ≔⌕AEθ›ι ¹ε¿ε✂θ⌊ε⊕⌈ε

Provalo online! Il collegamento è alla versione dettagliata del codice. Assicurati di includere un numero sufficiente di nuove righe nell'input anche se una delle parole chiave è vuota. Spiegazione:

≔⎇ζ…θ⌕θζθθ

Se la parola chiave end non è vuota, tronca la stringa alla prima comparsa. (Fortunatamente CycleChoptronca la stringa a vuoto se il suo input è negativo.)

≔⎇η⪫Φ⪪θηκηθθ

Se la parola chiave di inizio non è vuota, dividere la stringa sulla parola chiave, eliminare il primo elemento e unire nuovamente la stringa. Ciò si traduce in una stringa vuota se la parola chiave start non viene visualizzata nella stringa.

≔⌕AEθ›ι ¹ε

Controlla se la stringa contiene non spazi.

¿ε✂θ⌊ε⊕⌈ε

In tal caso, stampa dal primo all'ultimo non spazio.

DominicvanEssen Jan 11 2021 at 06:31

R , 111 byte

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

Provalo online!

Approccio diretto: trova le parole che delimitano usando regexpr(con argomento fixed = True per garantire che la stringa di testo non sia interpretata come regex), ottiene l' substrintervallo tra di loro e quindi trims il ritmo white sda entrambe le estremità.

Poiché le funzioni nchare regexprvengono utilizzate due volte ciascuna, è più breve definire alias a carattere singolo. Nel caso di nchar, possiamo anche ridefinire l'operatore unario ?come suo alias, in modo da evitare la necessità di parentesi. Sfortunatamente, questo trucco non è possibile qui a regexprcausa della necessità di alimentarlo con l'argomento aggiuntivo fixed = True.

pinkfloydx33 Jan 24 2021 at 20:05

C # 114 byte

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