2016-07-22 8 views
3

gefunden habe ich eine mehrzeilige Zeichenfolge wie folgt:Regex, die nur übereinstimmt, wenn keine doppelten Linien

SA21 abcdef 
BKxyz 
SA21 abcdef 

Ich brauche einen regulären Ausdruck, der nur übereinstimmt, wenn die Linie ^SA21 abcdef$ einmal vorhanden ist. So soll es nicht für das erste Beispiel passen, aber es sollte für dieses Spiel ein:

BK udsia 
SA21 abcdef 
BKxyz 

Ich habe versucht, die Leitung zu erfassen und sicherzustellen, dass es nur übereinstimmt, wenn die gleiche Zeile nicht später gefunden wird: /(^SA21 abcdef$)(?!\1)/mregex101 aber das tut funktioniert nicht, da es wahrscheinlich immer der letzten Zeile entspricht ...

+2

Versuchen Sie ['\ A (?: (?!^SA21 abcdef $).) * (^ SA21 abcdef $) (?: (?!^SA21 abcdef $).) * \ Z'] (https://www.regex101.com/r/vN4tQ9/1) (will nur wissen, ob das stimmt) ist die richtige Richtung). –

+2

Warum passen Sie es nicht einfach an, und prüfen Sie dann, wie viele Übereinstimmungen es gibt und machen Sie das 'if' dazu? –

+0

@FlorianPeschka Ich kann nicht einfach Code verwenden, wie wir die Regex von einem DSL verwenden – Chris

Antwort

2

Die gewünschte Regex sollte nur eine Zeile entsprechen, wenn die Zeile nicht vor oder nach dem einzelnen Auftreten der Zeile vorhanden ist. Dies wird mit einem temperierten gierigen Token erreicht:

/\A(?:(?!^SA21 abcdef$).)*(^SA21 abcdef$)(?:(?!^SA21 abcdef$).)*\z/ms 

Siehe regex demo

Die (?:(?!^SA21 abcdef$).)* ist das Token einen beliebigen Text passend, aber den Anfang der SA21 abcdef Linie. Der Modifizierer ist erforderlich, damit ein . mit einem Zeilenvorschub übereinstimmen kann.

jedoch das Konstrukt Ressource raubend ist, und es ist eine gute Idee, es entrollen:

/\A(?:\n+(?!SA21 abcdef$).*)*\n*^(SA21 abcdef)$(?:\n+(?!SA21 abcdef$).*)*\z/m 

another demo

Hinweis Siehe dass \A und \z eindeutiger Start/Ende String Anker sind, Der Modifikator /m beeinflusst sie nicht.

Muster Erklärung:

  • \A - Beginn der Zeichenfolge
  • (?:\n+(?!SA21 abcdef$).*)* - null oder mehr Sequenzen von:
    • \n+ - 1 oder mehr newlines ...
    • (?!SA21 abcdef$) - nicht gefolgt mit SA21 abcdef das ist die ganze Linie
    • .* - null oder mehr Zeichen andere als eine neue Zeile
  • \n* - null oder mehr Zeilenumbrüche
  • ^ - Anfang einer Zeile
  • (SA21 abcdef) - die Zeile, die
  • $ Single sein muss - Ende der Zeile
  • (?:\n+(?!SA21 abcdef$).*)* - siehe oben
  • \z - Ende der Zeichenfolge.
+1

funktioniert perfekt ... vielen Dank – Chris

Verwandte Themen