1021 Stimmen

Reguläre Ausdrücke: Gibt es einen AND-Operator?

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.

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.

516voto

Jason Cohen Punkte 78227

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.

0 Stimmen

Setzt du sie einfach alle in eine Reihe, ohne Trennzeichen dazwischen? z. B. (?=Apfel)(?=Orange)(?=Birne)

0 Stimmen

Trennzeichen (oder beliebige Zeichen) würden anzeigen, dass diese vor der nächsten nicht-verbrauchenden Gruppe stehen müssen.

0 Stimmen

Ich glaube nicht, dass es genau das ist, was er meint.

480voto

Alan Moore Punkte 70949

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

9 Stimmen

Genau richtig - auch dazu gibt es ein Tutorial! ocpsoft.org/tutorials/reguläre-ausdrücke/und-in-regex

11 Stimmen

Vielen Dank * das macht einen Unterschied

4 Stimmen

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

53voto

fanjabi Punkte 1468

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)

31 Stimmen

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.

0 Stimmen

@marvin_dpr Es funktionierte bei mir in CMake, während der andere Vorschlag (?=expr) nicht. Es scheint von der Implementierung abhängig zu sein.

46 Stimmen

Tut es nicht ^ bedeutet "Anfang der Zeichenkette" in der Regex-Syntax?

43voto

yodabar Punkte 4421

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

42 Stimmen

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.

2 Stimmen

@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.

15voto

user54579 Punkte 4397

Ist es in Ihrem Fall nicht möglich, die UND-Verknüpfung mit mehreren übereinstimmenden Ergebnissen durchzuführen? in Pseudocode

regexp_match(pattern1, data) && regexp_match(pattern2, data) && ...

3 Stimmen

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!

0 Stimmen

@AlanWolfe Ich habe jetzt genau den gleichen Fall ... haben Sie also den richtigen Ansatz gefunden, um mit dem logischen UND umzugehen?

CodeJaeger.com

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.

Powered by:

X