2009-05-15 14 views
34

Nach Benutzereingabe für verschiedene Bedingungen wieKombinieren Regexp

  1. Beginnt mit dem Sammeln: /(^@)/
  2. Endet mit: /(@$)/
  3. Enthält: /@/
  4. nicht enthält

zu make single regex wenn Benutzer mehrere Bedingungen eingeben, Ich kombiniere sie mit "|" so, wenn 1 und 2 es /(^@)|(@$)/

wird gegeben

Diese Methode funktioniert bisher aber,

Ich bin nicht in der Lage richtig zu bestimmen, Was sollte regex für 4 die Bedingung sein? Und kombiniere Regex auf diese Weise Arbeit?


Update: @ (Benutzereingabe) nicht gleichen für zwei Bedingungen sein und nicht alle vier Bedingungen immer vorhanden, aber sie können sein und in Zukunft könnte ich mehr Bedingungen müssen wie „ist genau "und" ist genau nicht "usw. so bin ich neugieriger zu wissen, dass dieser Ansatz wird skalieren?

Auch gibt es möglicherweise Probleme der Benutzereingabe Bereinigung, so Regex richtig maskiert, aber , die jetzt ignoriert wird.

+0

Update: Zweck der Kombination Regex ist es, wenn Bedingungen zu Single zu reduzieren. Weil diese Regex gegen eine große Anzahl von Strings passen wird. – nexneo

+1

was meinst du mit "nicht enthält"? – sarsnake

+0

Wenn die Benutzereingabe "cool" ist und die Zeichenfolge dieses Wort nicht enthält, bedeutet dies, dass sie übereinstimmt. – nexneo

Antwort

62

Werden die Bedingungen ODER-verknüpft oder UND-verknüpft?

Starts with: abc 
Ends with: xyz 
Contains: 123 
Doesn't contain: 456

Die OR-Version ist ziemlich einfach; Wie Sie gesagt haben, ist es hauptsächlich eine Frage der Rohre zwischen den einzelnen Bedingungen einfügen. Die Regex hört einfach auf, nach einer Übereinstimmung zu suchen, sobald eine der Alternativen übereinstimmt.

/^abc|xyz$|123|^(?:(?!456).)*$/ 

Die vierte Alternative bizarr aussehen, aber das ist, wie Sie Express „enthalten nicht“ in einem regulären Ausdruck. Die Reihenfolge der Alternativen spielt übrigens keine Rolle; Dies ist effektiv die gleiche Regex:

/xyz$|^(?:(?!456).)*$|123|^abc/ 

Die AND-Version ist komplizierter. Nachdem jede einzelne Regex übereinstimmt, muss die Match-Position auf Null zurückgesetzt werden, so dass die nächste Regex Zugriff auf die gesamte Eingabe hat. Das bedeutet, dass alle Bedingungen als Lookaheads ausgedrückt werden müssen (technisch muss einer von ihnen kein Vorausblick sein, ich denke, dass es die Absicht so deutlicher ausdrückt). Ein endgültiges .*$ vollendet das Spiel.

/^(?=^abc)(?=.*xyz$)(?=.*123)(?=^(?:(?!456).)*$).*$/ 

Und dann gibt es die Möglichkeit von kombinierten AND- und OR-Bedingungen - dort beginnt der wahre Spaß. : D

+2

Ja, mir geht es jetzt gut mit OR. Aber danke für die AND-Version. Kombination von UND und ODER ist nicht für mich. :) – nexneo

+1

Ich habe versucht, die letzte UND regex und ich bemerkte, dass es einen Syntaxfehler hat, ein extra ")" am Ende. Ich entfernte diesen Charakter, aber die Regex schien nicht wie vorgesehen zu funktionieren, nicht sicher, was ich falsch gemacht habe? Ich verwende .Net zum Testen. –

+0

Es ist eigentlich der vorletzte ')', der da nicht hingehört. Sobald das behoben ist, ist der Grund, warum es nicht funktioniert, weil nichts darin ist, das Charaktere verbraucht - es ist alles Lookaheads. Ich könnte den letzten Teil nicht zu einem Lookahead machen, aber um der Klarheit willen würde ich lieber ein '. *' Zum Ende hinzufügen. Ich repariere es jetzt; Danke, dass du mich darauf aufmerksam gemacht hast. –

3

Enthält keine @:/(^ [^ @] * $)/

funktioniert, wenn das beabsichtigte Ergebnis der Kombination ist, dass jeder von ihnen passenden Ergebnisse in der gesamten regulären Ausdruck passende Kombination.

2

Wenn eine Zeichenfolge nicht @ enthalten muss, muss jedes Zeichen ein anderes Zeichen als @ sein:

/^[^@]*$/ 

Dies wird eine beliebige Zeichenfolge beliebiger Länge übereinstimmen, die nicht @ enthält. Eine andere mögliche Lösung wäre es, das boolesche Ergebnis von /@/ zu invertieren.

2

In meiner Erfahrung mit Regex müssen Sie sich wirklich darauf konzentrieren, was genau Sie versuchen zu entsprechen, anstatt, was nicht übereinstimmen.

beispiels \ d {2}

[1-9] [0-9]

Der erste Ausdruck wird alle 2 Ziffern entsprechen .... und die zweite wird übereinstimmen 1 Stelle von 1 bis 9 und 1 Ziffer - jede Ziffer. Wenn Sie also 07 eingeben, wird der erste Ausdruck dies bestätigen, der zweite jedoch nicht.

Sehen Sie diese für fortgeschrittene Referenz:

http://www.regular-expressions.info/refadv.html

EDITED:

^((?!my string).)*$ Ist der reguläre Ausdruck für nicht "my string" enthalten.

+0

Können Sie mehr Details darüber geben, wie die Bedingung "Enthält nicht" mit dem obigen Vorschlag übereinstimmt. – nexneo

+1

Ich nehme an, Sie wollen einen Ausdruck, der etwas nicht enthält (es ist nicht klar, was der Ausdruck nicht enthalten soll). Mein Vorschlag zeigt, wie Sie es tun würden, wenn Sie nicht möchten, dass der Ausdruck an der ersten Stelle eine Ziffer 0 enthält. In diesem Fall würden Sie die erste Positionsziffer auf 1 bis 9 begrenzen. Es ist nicht sehr klar, was Sie mit "enthält nicht" meinen. Enthält was nicht? Bitte klären Sie, damit wir Ihnen helfen können. Meine Antwort war eher eine allgemeine Antwort.Entschuldigung, wenn dir das nicht geholfen hat. – sarsnake

+0

gnomixa, Bit-Test zeigt Ihre Version funktioniert gut. – nexneo

1

Die Kombination der Regex für die vierte Option mit einer der anderen funktioniert nicht innerhalb einer Regex. 4 + 1 würde bedeuten, dass die Zeichenfolge entweder mit @ oder gar nicht mit @ beginnt. Sie werden zwei separate Vergleiche benötigen, um das zu tun.

+0

@ wird nicht für zwei Bedingungen und nicht alle vier Bedingungen immer gleich, aber sie können sein und in Zukunft könnte ich mehr Bedingungen wie "ist genau" und "ist nicht genau" usw. so , Ich bin mehr neugierig zu wissen, dass dieser Ansatz skalieren wird? – nexneo

2

1 + 2 + 4 Bedingungen: starts | Enden, aber nicht in der Mitte

/^@[^@]*@?$|^@?[^@]*@$/ 

ist fast das gleiche, dass:

/^@?[^@]*@?$/ 

aber dieses eine beliebige Zeichenfolge übereinstimmt, ohne @ , Beispiel 'mein Name ist hal9000'