Natürlich können Sie die |
(Rohr?) zu repräsentieren OR
aber gibt es eine Möglichkeit, die AND
auch?
Konkret möchte ich Textabschnitte abgleichen, die ALLE einen bestimmten Satz enthalten, aber in keiner bestimmten Reihenfolge.
Natürlich können Sie die |
(Rohr?) zu repräsentieren OR
aber gibt es eine Möglichkeit, die AND
auch?
Konkret möchte ich Textabschnitte abgleichen, die ALLE einen bestimmten Satz enthalten, aber in keiner bestimmten Reihenfolge.
Verwenden Sie einen nicht-verbrauchenden regulären Ausdruck.
Die typische (d.h. Perl/Java) Notation ist:
(?=
expr )
Dies bedeutet "Übereinstimmung expr aber danach wird der Abgleich am ursprünglichen Abgleichspunkt fortgesetzt."
Sie können so viele davon machen, wie Sie wollen, und dies wird ein "und" sein. Beispiel:
(?=match this expression)(?=match this too)(?=oh, and this)
Sie können sogar Erfassungsgruppen innerhalb der nicht-verbrauchenden Ausdrücke hinzufügen, wenn Sie einige der darin enthaltenen Daten speichern müssen.
Setzt du sie einfach alle in eine Reihe, ohne Trennzeichen dazwischen? z. B. (?=Apfel)(?=Orange)(?=Birne)
Trennzeichen (oder beliebige Zeichen) würden anzeigen, dass diese vor der nächsten nicht-verbrauchenden Gruppe stehen müssen.
Sie müssen Lookahead verwenden, wie einige der anderen Teilnehmer bereits gesagt haben, aber der Lookahead muss andere Zeichen zwischen dem Zielwort und der aktuellen Trefferposition berücksichtigen. Zum Beispiel:
(?=.*word1)(?=.*word2)(?=.*word3)
Le site .*
in der ersten Vorausschau lässt es so viele Zeichen übereinstimmen, wie es braucht, bevor es zu "word1" kommt. Dann wird die Übereinstimmungsposition zurückgesetzt und der zweite Lookahead sucht nach "Wort2". Nochmals zurückgesetzt, und der letzte Teil entspricht "Wort3"; da es das letzte Wort ist, nach dem Sie suchen, ist es nicht notwendig, dass es in einem Lookahead steht, aber es schadet nicht.
Um einen ganzen Absatz abzugleichen, müssen Sie die Regex an beiden Enden verankern und eine abschließende .*
um die restlichen Zeichen zu verbrauchen. In der Perl-Schreibweise wäre das so:
/^(?=.*word1)(?=.*word2)(?=.*word3).*$/m
Der Modifikator 'm' steht für den Mehrzeilenmodus; er lässt die ^
y $
an Absatzgrenzen ("Zeilengrenzen" in Regex-Sprache) übereinstimmen. In diesem Fall ist es wichtig, dass Sie ノット den Modifikator "s" verwenden, mit dem das Metazeichen "dot" sowohl auf Zeilenumbrüche als auch auf alle anderen Zeichen passt.
Schließlich wollen Sie sicherstellen, dass Sie ganze Wörter und nicht nur Fragmente längerer Wörter finden, also müssen Sie Wortgrenzen hinzufügen:
/^(?=.*\bword1\b)(?=.*\bword2\b)(?=.*\bword3\b).*$/m
Genau richtig - auch dazu gibt es ein Tutorial! ocpsoft.org/tutorials/reguläre-ausdrücke/und-in-regex
+1 für die klare und prägnante Antwort, die eine der besten Verwendungsmöglichkeiten für Lookaheads aufzeigt (im Gegensatz zu Verwendungsmöglichkeiten wie einem Hack, der die prozentuale Übereinstimmung eines Passworts zählt) :)
Sehen Sie sich dieses Beispiel an:
Wir haben 2 Regexps A und B und wollen beide abgleichen, also sieht es in Pseudocode wie folgt aus:
pattern = "/A AND B/"
Sie kann ohne den Operator AND wie folgt geschrieben werden:
pattern = "/NOT (NOT A OR NOT B)/"
in PCRE:
"/(^(^A|^B))/"
regexp_match(pattern,data)
Das stimmt zwar für die formale Logik, ist aber hier absolut keine Hilfe. In Regexen kann NOT noch schwieriger auszudrücken sein als AND.
@marvin_dpr Es funktionierte bei mir in CMake, während der andere Vorschlag (?=expr)
nicht. Es scheint von der Implementierung abhängig zu sein.
Der Operator AND ist implizit in der RegExp-Syntax.
Der OR-Operator muss stattdessen mit einer Pipe angegeben werden.
Die folgenden RegExp:
var re = /ab/;
bedeutet der Buchstabe a
UND der Brief b
.
Es funktioniert auch mit Gruppen:
var re = /(co)(de)/;
bedeutet dies, dass die Gruppe co
UND die Gruppe de
.
Um das (implizite) UND durch ein ODER zu ersetzen, wären folgende Zeilen erforderlich:
var re = /a|b/;
var re = /(co)|(de)/;
Leider ist dies nicht das, wonach der Auftraggeber gefragt hat. Das Programm findet alles in dieser Reihenfolge, während er sie in beliebiger Reihenfolge haben wollte. Sehen Sie sich die Antwort von stackoverflow.com/users/20938/alan-moore unten, welche die richtige ist.
@JESii danke für Ihren Hinweis, Sie haben Recht und ich habe die Frage von Hugoware falsch verstanden, ich habe mich besonders auf seinen ersten Satz konzentriert. Die richtige Antwort ist eine korrekte Verwendung des Lookahead-Operators, wie AlanMoore schrieb. Wie auch immer, ich denke, jemand könnte meine Klarstellung nützlich finden, da sie bereits hochgestuft wurde, also würde ich nicht alles wegwerfen. Mit freundlichen Grüßen.
Ich bin in einer Situation, wo ich einige Code, der eine Datentabelle von Regeln ist, mit einem einzigen Regex-Muster-Match-String, um die Gültigkeit der Regel zu testen haben. Verschieben auf mehrere Tests ist nicht etwas, das ich in meinem Fall tun können, und in der Regel in andere Leute' Fälle auch!
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
2 Stimmen
Meinen Sie damit, dass Sie Phrasen in einem Text finden wollen, wobei jede dieser Phrasen eine gültige Permutation der Wörter in einer gegebenen Phrase ist?
3 Stimmen
Ich stelle das hier rein, weil drei oder vier Antworten es ignorieren. Lookahead stimmt nicht für jede Klausel mit der gleichen Länge überein, es sei denn, sie enden auf $. Ein Lookahead könnte auf vier Zeichen passen, ein anderer auf 6. Zum Beispiel wird (?=a*)(?=aab) mit aabaaaaba übereinstimmen.
4 Stimmen
Versuchen Sie, nur das "Leerzeichen" für den Operator "AND" zu verwenden.
0 Stimmen
1.
I'd like to match paragraphs of text
. 2. Enthält außer Betrieb Text. Nummer 1 ist offen für Interpretationen. Für Nummer 2 gibt es mehrere Möglichkeiten. Weg 1:(?:(?:(?(1)(?!))\b(phrase1)\b.*?|(?(2)(?!))\b(phrase2)\b.*?)){2}
, Weg 2:(?=.*\bphrase1\b)(?=.*\bphrase2\b)
wobei die Übereinstimmung des Absatzes in diesem Fall unbestimmt ist, bis die Definition des Absatzes formalisiert ist.