Kurze Antwort: Sie können nicht tun, was Sie fragen. Technisch hat der erste Teil eine hässliche Antwort, aber der zweite Teil (wie ich es verstehe) hat keine Antwort.
Für Ihren ersten Teil habe ich eine ziemlich unpraktische (noch pure Regex) Antwort; etwas Besseres würde Code erfordern (wie @ rednaws viel sauberere Antwort oben). Ich fügte dem Test hinzu, um es umfassender zu machen. (Der Einfachheit halber verwende ich grep -Pio
für PCRE, Groß- und Kleinschreibung, Druck ein Spiel pro Zeile.)
$ echo "Ben sits on a bench better end" \
|grep -Pio '(?=b(?!en)|(?<!b)en|e(?!n)|(?<!be)n|[^ben])\w+'
sits
on
a
ch
better
end
Ich bin im Grunde ein Sonderfall für jeden Buchstaben in „ben“ zu machen, damit ich nur Iterationen umfassen kann die nicht selbst Teil der Zeichenfolge "ben" sind. Wie gesagt, nicht wirklich praktisch, auch wenn ich technisch deine Frage beantworte. Ich habe auch a blow-by-blow explanation of this regex gespeichert, wenn Sie weitere Details wünschen.
Wenn Sie gezwungen sind, eine reine Regex anstelle von Code zu verwenden, ist Ihre beste Wette für solche Artikel, Code in zu schreiben generieren die Regex. Auf diese Weise können Sie eine saubere Kopie davon behalten.
Ich bin mir nicht sicher, was Sie für den Rest Ihrer Herausforderung fragen; ein regulärer Ausdruck ist entweder gierig oder faul [1][2], und ich weiß nicht von irgendwelchen Implementierungen, die „jede Kombination“ und nicht nur die erste Kombination von beiden Verfahren finden können. Wenn es so etwas gäbe, wäre es im wirklichen Leben sehr langsam (eher als schnelle Beispiele); Die langsame Geschwindigkeit von Regex-Engines wäre nicht hinnehmbar, wenn sie gezwungen wären, jede Möglichkeit zu prüfen, die im Grunde genommen eine ReDoS wäre.
Beispiele:
# greedy evaluation (default)
$ echo 1a2be3 |grep -Pio '(?!\d[a-z]\d)\w+'
a2be3
# lazy evaluation
$ echo 1a2be3 |grep -Pio '(?!\d[a-z]\d)\w+?'
a
2
b
e
3
Ich nehme an, Sie suchen 1
1a
a
a2
a2b
a2be
a2be3
2
2b
2be
2be3
b
be
be3
e
e3
3
aber ich glaube nicht, dass Sie mit einer reinen Regex bekommen . Du benötigst etwas Code, um jede Teilzeichenkette zu generieren, und dann kannst du eine Regex verwenden, um das verbotene Muster herauszufiltern (wieder geht es hier um gierige vs faul vs ReDoS).
Es klingt wie Sie können einfach eine Regex ersetzen Sie Ihre Blacklisted Muster mit der leeren Zeichenfolge und sehen, ob etwas bleibt? – Jon
Können Sie mit einem Beispiel antworten? – Srb1313711
@ Srb1313711 Jede Programmiersprache der Wahl? Ich bin mir nicht sicher, ob das Ersetzen in einer Regex allein erfolgen kann. – skiwi