11 Stimmen

Wie schließe ich ein boolesches AND in eine Regex ein?

Gibt es eine Möglichkeit, einen einzelnen Regex zu erhalten, der diese Bedingung erfüllt?

Ich suche ein "Wort", das drei Buchstaben aus dem Satz MBIPI enthält, in beliebiger Reihenfolge, aber ein I enthalten MUSS.

d. h.

re.match("[MBDPI]{3}", foo) und "I" in foo

Dies ist also das korrekte Ergebnis (in Python mit dem re-Modul), aber kann ich dies von einem einzigen Regex erhalten?

>>> for foo in ("MBI", "MIB", "BIM", "BMI", "IBM", "IMB", "MBD"):
...     print foo,
...     print re.match("[MBDPI]{3}", foo) and "I" in foo
MBI True
MIB True
BIM True
BMI True
IBM True
IMB True
MBD False

mit regex Ich weiß, ich kann | als boolesche OR-Operator verwenden, aber gibt es eine boolesche AND-Äquivalent?

oder brauche ich vielleicht eine Vorwärts- oder Rückwärtssuche?

0 Stimmen

Sie können auch mit str.find() nach dem Zeichen 'I' suchen. Quelle: docs.python.org/library/stdtypes.html#str.find

5voto

Jens Punkte 24565

Sie können ein boolesches AND vortäuschen, indem Sie Lookaheads verwenden. Gemäß http://www.regular-expressions.info/lookaround2.html wird dies in Ihrem Fall funktionieren:

"\b(?=[MBDPI]{3}\b)\w*I\w*"

0 Stimmen

Wahrscheinlich müssen die Wortgrenzen überprüft werden, aber ansonsten +1, clevere Lösung.

4voto

Jan Heldal Punkte 128

mit regex Ich weiß, ich kann | als boolesche OR-Operator verwenden, aber gibt es eine boolesche AND-Äquivalent?

A und B = nicht ( nicht A oder nicht B) = (?![^A]|[^B])

A und B sind Ausdrücke, die tatsächlich gemeinsame Mitglieder haben können.

3voto

cletus Punkte 596503

Das ist so ziemlich das Einzige, was Sie tun können:

\b(I[MBDPI]{2}|[MBDPI]I[MBDPI]|[MBDPI]{2}I)\b

El \b Zeichen entspricht einer Wortgrenze mit der Breite Null. Dadurch wird sichergestellt, dass Sie etwas finden, das genau drei Zeichen lang ist.

Ansonsten stößt man an die Grenzen dessen, was ein reguläre Sprache tun können.

Eine Alternative ist die Anpassung:

\b[MBDPI]{3}\b

diese Gruppe zu erfassen und dann nach einem I zu suchen.

Bearbeiten: Um eine vollständige Antwort zu erhalten, werde ich mich anpassen Jens' Antwort die die Testen desselben Teils einer Zeichenfolge für mehr als eine Bedingung :

\b(?=[MBDPI]{3}\b)\w*I\w*

mit der Wortbegrenzungsprüfung, um sicherzustellen, dass es nur drei Zeichen lang ist.

Dies ist eine etwas fortschrittlichere Lösung und in mehr Situationen anwendbar, aber ich würde im Allgemeinen das bevorzugen, was leichter zu lesen ist (imho die "oder"-Version).

0 Stimmen

OMFG!! danke, die einfacher zu lesende Version funktioniert bei mir nicht, ABER, Ihr allgemeines Beispiel und der Link zur Umgehung haben mir das Hirn gerettet!! obwohl viel schwieriger zu LESEN, ist es die einzige Methode, wenn der bedingte Satz viel komplexer wird. Mein Anwendungsfall (?=(Muster1|Muster2)) (Muster1)? (muster2)? muster3 Hässlich zu lesen, aber die einzig sinnvolle Lösung.

2voto

Bart Kiers Punkte 160101

Sie könnten Lookahead verwenden, um zu sehen, ob eine I vorhanden ist:

(?=[MBDPI]{0,2}I)[MBDPI]{3}

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