Sub-String-Extraktor mit bestimmten Schlüsselwörtern
Herausforderung
Das Ziel dieser Herausforderung besteht darin, eine Funktion zu erstellen, die eine Eingabezeichenfolge, ein Startschlüsselwort und ein Endschlüsselwort verwendet. Das aus der Ausgabe extrahierte Ergebnis ist vom angegebenen Startschlüsselwort bis zum Endschlüsselwort (aber ausgeschlossen). Die Ausgabe-Unterzeichenfolge folgt den folgenden Regeln.
In allen Fällen sollten die führenden / nachfolgenden Leerzeichen in der Ausgabeunterzeichenfolge entfernt werden.
Wenn das angegebene Schlüsselwort start eine leere Zeichenfolge ist, bedeutet dies, dass sich der Anker am Anfang der Eingabezeichenfolge befindet. Andernfalls ist das erste Auftreten des angegebenen Startschlüsselworts ein Startanker. Wenn das angegebene Schlüsselwort start nicht vorkommt, ist die Ausgabe eine leere Zeichenfolge.
Wenn das angegebene Schlüsselwort end eine leere Zeichenfolge ist, bedeutet dies, dass sich der Anker am Ende der Eingabezeichenfolge befindet. Andernfalls ist das erste Auftreten des angegebenen Schlüsselworts end ein Endanker. Wenn das angegebene Schlüsselwort end nicht vorkommt, ist die Ausgabe eine leere Zeichenfolge.
Wenn die Position des Startankers nach der Position des Endankers liegt oder sich ein Teil des ersten Auftretens des angegebenen Startschlüsselworts und ein Teil des ersten Auftretens des angegebenen Endschlüsselworts überlappen, ist die Ausgabe eine leere Zeichenfolge.
Ähnlich, aber anders als beim Extrahieren einer Zeichenfolge aus einer bestimmten Zeichenfolge , bestehen die angegebenen Start- und Endanker aus mehreren Zeichen.
Hier ist eine ungolfed Referenzimplementierung 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();
}
Beispiel für Ein- und Ausgabe
Die Beispiel-Ein- und Ausgabe ist wie folgt aufgeführt.
Eingabezeichenfolge | Schlüsselwort starten | Schlüsselwort beenden | Ausgabe |
---|---|---|---|
"C # wurde um 2000 von Microsoft im Rahmen seiner .NET-Initiative entwickelt." | ""(leerer String) | ""(leerer String) | "C # wurde um 2000 von Microsoft im Rahmen seiner .NET-Initiative entwickelt." |
"C # wurde um 2000 von Microsoft im Rahmen seiner .NET-Initiative entwickelt." | ""(leerer String) | ".NETZ" | "C # wurde um 2000 von Microsoft als Teil seiner" |
"C # wurde um 2000 von Microsoft im Rahmen seiner .NET-Initiative entwickelt." | "C #" | ""(leerer String) | "wurde um 2000 von Microsoft im Rahmen seiner .NET-Initiative entwickelt" |
"C # wurde um 2000 von Microsoft im Rahmen seiner .NET-Initiative entwickelt." | "C #" | ".NETZ" | "wurde um 2000 von Microsoft im Rahmen seiner" |
"C # wurde um 2000 von Microsoft im Rahmen seiner .NET-Initiative entwickelt." | ".NETZ" | ""(leerer String) | "Initiative" |
"C # wurde um 2000 von Microsoft im Rahmen seiner .NET-Initiative entwickelt." | ""(leerer String) | "C #" | ""(leerer String) |
"C # wurde um 2000 von Microsoft im Rahmen seiner .NET-Initiative entwickelt." | ".NETZ" | "C #" | ""(leerer String) |
"C # wurde um 2000 von Microsoft im Rahmen seiner .NET-Initiative entwickelt." | "ABC" | "C #" | ""(leerer String) |
"C # wurde um 2000 von Microsoft im Rahmen seiner .NET-Initiative entwickelt." | ".NETZ" | "XYZ" | ""(leerer String) |
"C # wurde um 2000 von Microsoft im Rahmen seiner .NET-Initiative entwickelt." | "ABC" | "XYZ" | ""(leerer String) |
Regeln
Das ist Code-Golf . Die Antwort mit den wenigsten Bytes gewinnt.
Antworten
APL (Dyalog Extended) , 24 Byte ( SBCS )
Vollständiges Programm, das zur Eingabe eines Arrays von auffordert [EndKeyword,StartKeyword,InputString]
. Erfordert eine 0-basierte Indizierung.
⌂deb⊃(⌽⊢↓⍨1⍳⍨⊣,⍷)/⌽¨@0⊢⎕
Probieren Sie es online aus!
⎕
Eingabeaufforderung
⊢
auf diesem…
⌽¨@0
Kehren Sie alle Elemente um, die bei Offset 0 auftreten
(
… )/
Mit der folgenden stillschweigenden Funktion von rechts reduzieren:
⍷
Geben Sie mit einer Booleschen Liste alle Stellen an, an denen das linke Argument im rechten Argument beginnt
⊣,
Stellen Sie dem linken Argument das voran
1⍳⍨
Finden Sie den Versatz der ersten 1
⊢↓⍨
Löschen Sie so viele führende Elemente aus dem richtigen Argument
⌽
umkehren (beim nächsten Mal tun Sie dies ab dem Ende und danach die Reihenfolge zurücksetzen)
⊃
offenbaren das Gehäuse, das durch die Reduktion von einem eindimensionalen Array zu einem 0-dimensionalen Array verursacht wird
⌂deb
d elete e nding (führende und nachfolgende ) b lanks
JavaScript (ES6), 80 bis 75 Byte
Dies enthält einige nicht druckbare Zeichen, die unten maskiert sind.
(s,a,b)=>s.replace(b||/$/,"").replace(a,"").match(/ *(.*?) *|$/)[1]||""
Probieren Sie es online aus!
Kommentiert
(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 Bytes
9 Bytes dank movatica gespart !!!
2 Bytes dank Ovs gespeichert !!!
lambda s,a,b:s[s.find(a):(b in s)*s.find(b)if b else None][len(a):].strip()
Probieren Sie es online aus!
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()
Probieren Sie es online aus!
Recht einfach...
Ruby , 66 Bytes
->w,s,e,r=Regexp{"#{w[/#{r.quote s}\K.+(?=#{r.quote e})/]}".strip}
Probieren Sie es online aus!
Eine andere Methode ohne die Verwendung von Regex,
Ruby , 72 Bytes
->w,s,e{"#{w[((w+s).index(s)+s.size rescue 0)...w.rindex(e)||0]}".strip}
Probieren Sie es online aus!
Python 3 , 100 85 Bytes
Die Regex-Version kann den Slicing-Algorithmus immer noch nicht übertreffen .
from re import*
r=escape
f=lambda s,b,e:(search(r(b)+'(.+)'+r(e),s)or' ')[1].strip()
Probieren Sie es online aus!
Retina 0,8,2 , 60 Bytes
(.*)¶(.+)?¶.*?\1 *(.*?) *(?<!(?=\2).*)(?(2)\2.*|$)|(.|¶)+ $3
Probieren Sie es online aus! Nimmt die Eingabe als Start, Ende, Zeichenfolge in separaten Zeilen auf, aber die Verknüpfung dient zur Testsuite mit einem Header, der der Einfachheit halber aus einer durch Kommas getrennten Zeichenfolge, Ende und Start konvertiert wird. Erläuterung:
(.*)¶
Passen Sie das Schlüsselwort start an.
(.+)?¶
Entspricht optional einem nicht leeren End-Schlüsselwort.
.*?\1
Suchen Sie das Schlüsselwort start so früh wie möglich in der Zeichenfolge sowie optionale Leerzeichen.
*(.*?) *
Passen Sie ein möglichst kurzes Ergebnis an (damit das Schlüsselwort end so früh wie möglich in der Zeichenfolge gefunden wird), aber schneiden Sie auch Leerzeichen um das Ergebnis herum ab.
(?<!(?=\2).*)
Stellen Sie sicher, dass das Schlüsselwort end zu diesem Zeitpunkt noch nicht übergeben wurde.
(?(2)\2.*|$)
Wenn das Schlüsselwort end leer war, stimmen Sie nur am Ende der Zeichenfolge überein, andernfalls stimmen Sie mit dem Schlüsselwort end und dem Rest der Zeichenfolge überein.
|(.|¶)+
Wenn es nicht möglich war, etwas abzugleichen, löschen Sie alles.
$3
Behalten Sie das gewünschte Ergebnis.
Wolfram Language (Mathematica) , 93 Bytes
sStringTrim@StringTake[s,i=1;If[i*=-1;#=="",0,StringPosition[s,#][[1,i]]]-i&/@#]/._@_:>""&
Probieren Sie es online aus!
Rot , 90 Bytes
func[t s e][p:""if""<> s[append s" "]if e =""[e:[end]]parse t[thru s copy p to[opt" "e]]p]
Probieren Sie es online aus!
C (gcc) , 168 152 143 132 112 Bytes
Ein enormer -38 dank @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;}
Probieren Sie es online aus!
JavaScript (ES6) 95 92 Bytes, kein Regex!
(i,s,e,t=i.indexOf(s),r=i.lastIndexOf(e))=>t!=-1&r!=-1?(i.substring(t+s.length,r)).trim():''
Wie man es versucht:
Öffnen Sie die JavaScript-Konsole Ihres Browsers und fügen Sie Folgendes ein.
((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')
Holzkohle , 41 Bytes
≔⎇ζ…θ⌕θζθθ≔⎇η⪫Φ⪪θηκηθθ≔⌕AEθ›ι ¹ε¿ε✂θ⌊ε⊕⌈ε
Probieren Sie es online aus! Der Link führt zur ausführlichen Version des Codes. Achten Sie darauf, genügend Zeilenumbrüche in die Eingabe aufzunehmen, auch wenn eines der Schlüsselwörter leer ist. Erläuterung:
≔⎇ζ…θ⌕θζθθ
Wenn das Schlüsselwort end nicht leer ist, schneiden Sie die Zeichenfolge beim ersten Auftreten ab. (Glücklicherweise wird CycleChop
die Zeichenfolge abgeschnitten, um sie zu leeren, wenn ihre Eingabe negativ ist.)
≔⎇η⪫Φ⪪θηκηθθ
Wenn das Schlüsselwort start nicht leer ist, teilen Sie die Zeichenfolge auf das Schlüsselwort auf, verwerfen Sie das erste Element und verbinden Sie die Zeichenfolge erneut. Dies führt zu einer leeren Zeichenfolge, wenn das Schlüsselwort start nicht in der Zeichenfolge angezeigt wird.
≔⌕AEθ›ι ¹ε
Überprüfen Sie, ob die Zeichenfolge Leerzeichen enthält.
¿ε✂θ⌊ε⊕⌈ε
Wenn ja, drucken Sie vom ersten bis zum letzten Leerzeichen.
R , 111 Bytes
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)))
Probieren Sie es online aus!
Geradliniger Ansatz: Funde Worte begrenzt regexpr
(mit dem Argumente f
ixed = T
rue um sicherzustellen , dass die Textzeichenfolge nicht als Regex interpretiert), bekommen das substr
ing zwischen ihnen, und dann trim
s das w
hite s
Tempo von beiden Enden.
Da die Funktionen nchar
und regexpr
jeweils zweimal verwendet werden, ist es kürzer, Aliase mit einem Zeichen zu definieren. Im Fall von nchar
können wir sogar den unären Operator ?
als Alias neu definieren , sodass keine Klammern erforderlich sind. Leider ist dieser Trick hier nicht möglich, regexpr
da das zusätzliche Argument f
ixed = T
rue eingegeben werden muss .
C # 114 Bytes
(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():"";}