ich nur schreiben enthält. Beide in perl
oder grep
sind in Ordnung. Vielen Dank.Wie man einen regulären Ausdruck schreiben, die `abc` oder` bcd` aber nicht `diy`, dass in einer Zeile
Antwort
Natürlich ist dies möglich mit regex einige Look-Ahead-Behauptungen mit
$i =~ /^(?=.*(?:abc|bcd))(?!.*diy)/
(?=.*(?:abc|bcd))
wird wahr sein, wenn eines der Teile ist da drin Sie
(?!.*diy)
fehl, wenn die Zeichenfolge, die Sie don‘ t wollen ist drin
Aber ich denke, Ihre Lösung ist klarer.
$ echo 'now I know my abcs' | txr -c '@/.*(abc|bcd).*&~.*diy.*/' -
$ echo 'no match' | txr -c '@/.*(abc|bcd).*&~.*diy.*/' -
false
$ echo 'Kaz wanted better regex, so he did the diy thing, starting from abc' | txr -c '@/.*(abc|bcd).*&~.*diy.*/' -
false
false
wird von einem gescheiterten Beendigungsstatus begleitet und zeigt keine Übereinstimmung. Keine Ausgabe bedeutet Übereinstimmung.
Wir verwenden .*
, weil die Übereinstimmung verankert ist. @/RE/
selbst in einer Zeile bedeutet, dass die Zeile mit der Regex übereinstimmen muss; wenn wir diese Linie von Anfang bis Ende der Regex-Maschine zuführen, ist die Maschine ein Akzeptanzzustand.
Wenn Sie solche Regexes haben, ist die Suche-Semantik in der Regex schlecht. I.e. wenn foo
eigentlich .*(foo).*
bedeutet (passen foo
irgendwo im Text), funktioniert das nicht sehr gut für foo&~bar
, weil .*(foo&~bar).*
nicht dasselbe bedeutet wie . Ersteres bedeutet "Übereinstimmung mit einer beliebigen Zeichenfolge, die eine Teilzeichenfolge enthält, die foo&~bar
entspricht." Aber das ist eine unmögliche Übereinstimmung; Kein String kann foo
und bar
gleichzeitig sein. Es ist eine leere Kreuzung. Letzteres bedeutet jedoch, dass "eine Zeichenkette, die foo
enthält, irgendwo darin enthalten ist, aber bar
nirgends enthält." Jetzt sind Sie im Geschäft.
Ich denke, dass Sie 'Grep' bekommen können, was diese Art von Sache von AT & T Forschung tut. – Kaz
Was ist 'txr' und woher kommt es? Es scheint nicht als Standard-Tool (Ports oder Packages) auf einem meiner FreeBSD oder Linux-Maschinen verfügbar zu sein. – ghoti
Es ist neu (<3 Jahre). Der Tag, an dem es so verfügbar ist, ist nicht angekommen. Für den Moment bauen Leute aus Quellen: http://www.nongnu.org/txr. – Kaz
Das Negieren einer Folge von Zeichen ist normalerweise ein Schmerz in Regex. Sie müssten Look-Ahead-Assertions verwenden.
Wenn Sie für zusammenhängende Sequenzen testen, könnten Sie versuchen, es mit Look-Ahead-und Look-Behinds zu tun, etwa (?<!diy)(abc|bcd)(?!diy)
, aber das wird wahrscheinlich mehrdeutig sein.
würde ich den Test wie der Ihren verlassen, nur das Standard-Variable zu verlieren:
if /(abc|bcd)/ and not /diy/
klar und sauber. :)
Vielen Dank ~ – madper
Sie müssten Lookahead-Operatoren verwenden, wenn Sie nicht die Unterstützung in der Regex haben; aber Negieren gehört definitiv in den Bereich eines endlichen Automaten. Wenn Sie Tabellen erstellen würden, gäbe es viele Zustände, aber es ist möglich ohne; zum Beispiel durch Algebra. Anstatt den Pfeilen von Blase zu Blase zu folgen, können Sie Ableitungen von Regex-Formel zu Regex-Formel durchführen. – Kaz
Das in einer anderen Antwort vorgeschlagene Lookahead/Behind funktioniert bei diesem Problem nicht. Um Lookbehind zu verwenden, benötigen Sie ein Lookback mit variabler Länge, das von Perl nicht unterstützt wird.
/^(?!.*?diy).*?(?:abc|bcd)/s
Ein anderer Ansatz:
/^(?:(?!diy).)*(?:abc|bcd(?!iy))(?:(?!diy).)*\z/s
In jedem Fall die bc aus dem Factoring | kann eine effizientere Regex erzeugen.
- 1. Wie man einen regulären Ausdruck schreiben
- 2. wie einen regulären Ausdruck schreiben
- 3. wie einen regulären Ausdruck zu schreiben, für die Herstellung einer csv aus Zeichenfolge zusätzliche Kommas entfernen
- 4. Wie man einen regulären Ausdruck für das Web schreiben
- 5. regulären Ausdruck benötigen die Rückseite eines Wortes in einer Zeile
- 6. Wie man einen regulären Ausdruck bekommen
- 7. Wie erstellt man diesen regulären Ausdruck?
- 8. Wie verwendet man regulären Ausdruck, um einen Teilzeichenfolgewert zu ersetzen?
- 9. einen regulären Ausdruck für nicht mit etwas
- 10. Konvertiere einen String in einen regulären Ausdruck
- 11. Warum der Eingang "abc !!!" aber die Ausgabe ist nicht "abC+++"?
- 12. übereinstimmende mehrere Zeile in regulären Python-Ausdruck
- 13. Wie bestimmte Zeile mit regulären Ausdruck
- 14. regulärer Ausdruck "enthält" einen anderen regulären Ausdruck
- 15. Wer kann mir helfen, einen regulären Ausdruck zu schreiben?
- 16. Wie man einen regulären Ausdruck in preg_match_all "und"
- 17. Wie man einen regulären Ausdruck konvertieren von OR XOR
- 18. Rubin regulären Ausdruck „bis leere Zeile gehen“
- 19. Ersetzen mit regulären Ausdruck
- 20. Unterschied zwischen zwei regulären Ausdrücken: [abc] + und ([abc]) +
- 21. regulären Ausdruck in glob.glob von Python mit
- 22. Wie findet man einen String, der^im regulären Ausdruck enthält?
- 23. Wie man einen Teil einer Regex abgleicht, aber nicht erfasst?
- 24. Wie kann ich einen langen regulären Ausdruck schreiben, damit er auf den Bildschirm passt?
- 25. Hilfe für einen regulären Ausdruck
- 26. Java regulären Ausdruck Zeichen in einer Zeichenfolge
- 27. In Python, wie einen regulären Ausdruck passenden Strings, beginnend mit String A zu schreiben, aber nicht mit B
- 28. Python regulären Ausdruck Hilfe
- 29. Wie ignoriert man Whitespace in einer Zeichenfolge für einen regulären Ausdruck?
- 30. Eine String-Match-Anforderung in einen regulären Ausdruck umwandeln
wird in diesem Fall ein Regexp schneller als zwei Regexps? – madper
@madper Sorry, aber ich denke, jede Antwort auf die Leistung wäre in diesem Fall eine wilde Vermutung. Wenn Sie dieses "wenn" sehr (sehr, sehr) oft machen, dann machen Sie einfach einen Benchmark. Wenn Sie dies von Zeit zu Zeit tun, verwenden Sie, was Sie besser mögen. – stema