2016-09-20 3 views
4

Ich muss alle Zeichenfolgen finden, die zu einem Muster passen, mit Ausnahme von zwei angegebenen Zeichenfolgen.Regulärer Ausdruck, der zu allen außer einer Zeichenfolge passt

Suchen Sie beispielsweise alle Buchstabengruppen mit Ausnahme von aa und bb. Ausgehend von dieser Zeichenfolge:

-a-bc-aa-def-bb-ghij- 

zurückkehren sollte:

('a', 'bc', 'def', 'ghij') 

ich mit this regular Ausdruck versucht, die vier Saiten einfängt. Ich dachte, ich würde mir näher kommen, aber (1) es funktioniert nicht in Python und (2) Ich kann nicht herausfinden, wie man ein paar Strings von der Suche ausschließt. (Ja, ich könnte sie später entfernen, aber mein richtiger regulärer Ausdruck macht alles auf einen Schlag und ich möchte diesen letzten Schritt darin einfügen.)

Ich sagte, es funktioniert nicht in Python, weil ich das probiert habe, genau die gleiche Ergebnis erwartet, aber stattdessen bekomme ich nur die erste Gruppe:

>>> import re 
>>> re.search('-(\w.*?)(?=-)', '-a-bc-def-ghij-').groups() 
('a',) 

ich mit negativem Vorgriff versucht, aber ich konnte nicht eine funktionierende Lösung für diesen Fall finden.

+0

Sie wollen ['findall'] (https://docs.python.org/2/library/re.html#re.findall) -' search' soll nur die erste Übereinstimmung zurückgeben :) – cxw

Antwort

6

Sie können von negativen Blick aheads machen.

Zum Beispiel

>>> re.findall(r'-(?!aa|bb)([^-]+)', string) 
['a', 'bc', 'def', 'ghij'] 

  • - Spiele -

  • (?!aa|bb) Negative Look-Ahead, prüft, ob - nicht durch aa oder bb gefolgt

  • ([^-]+) Spiele ony oder mehrere andere Zeichen als -


bearbeiten

Die obige regex werden diejenigen, die beginnen mit aa oder bb, zum Beispiel wie -aabc- nicht überein. Kümmern, dass wir - die Lookaheads hinzufügen können, wie,

>>> re.findall(r'-(?!aa-|bb-)([^-]+)', string) 
+0

Nur zur Info: Der '(?! Aa | bb) 'Lookahead verbietet jene Matches, die * mit * aa' oder' bb' beginnen. Also, sagen wir, "aacn" [wird nicht gefunden] (https://regex101.com/r/jR5sH1/1). –

+0

@ WiktorStribiżew Gültiger Punkt. Ich habe der Antwort eine Änderung hinzugefügt. Danke für das Aufzeigen :) – nu11p01n73R

+0

Ja, ich denke nur das '-' am Ende ist tatsächlich erforderlich - nur nach der OP-Eingabe-String zu urteilen. Wenn es am Ende kein '-' gibt, wird deine Regex ein Match zurückgeben, meins aber nicht. Dieser Punkt ist nicht klar, aber ich habe einen Downvote dafür. –

2

Sie müssen ein negatives Lookahead verwenden, um ein allgemeineres Muster einzuschränken, und re.findall, um alle Übereinstimmungen zu finden.

Verwenden

res = re.findall(r'-(?!(?:aa|bb)-)(\w+)(?=-)', s) 

oder - wenn Ihre Werte zwischen Bindestriche jeder aber einen Bindestrich sein können, verwenden Sie eine negierte Zeichenklasse [^-]:

res = re.findall(r'-(?!(?:aa|bb)-)([^-]+)(?=-)', s) 

Hier ist die regex demo.

Einzelheiten:

  • - - ein Bindestrich
  • (?!(?:aa|bb)-) - wenn es ein aa- oder bb- nach dem ersten Bindestrich ist, sollte keine Übereinstimmung
  • (\w+) zurückgegeben werden - Gruppe 1 (dieser Wert wird durch den re.findall Aufruf zurückgegeben) Erfassen von 1 oder mehr Wort Zeichen ODER[^-]+ - 1 oder mehr Zeichen andere als -
  • (?=-) - es muss eine - nach dem Wort Zeichen geben. Der Lookahead ist hier erforderlich, um überlappende Übereinstimmungen sicherzustellen (da dieser Bindestrich ein Ausgangspunkt für das nächste Spiel ist).

Python demo:

import re 
p = re.compile(r'-(?!(?:aa|bb)-)([^-]+)(?=-)') 
s = "-a-bc-aa-def-bb-ghij-" 
print(p.findall(s)) # => ['a', 'bc', 'def', 'ghij'] 
+0

Ich werde Fügen Sie diese Bemerkung auch hier hinzu: Ich denke, der letzte Lookahead ist erforderlich, da die letzte Übereinstimmung nur dann gültig ist, wenn sie mit '-' verfolgt wird. Das ergibt sich aus der OP-Zeichenfolge, also nicht so sicher. –

0

Obwohl eine regex Lösung gefragt wurde, ich würde behaupten, dass dieses Problem mit einfacher Python Funktionen leichter gelöst werden kann, nämlich String Splitting und Filterung:

input_list = "-a-bc-aa-def-bb-ghij-" 
exclude = set(["aa", "bb"]) 
result = [s for s in input_list.split('-')[1:-1] if s not in exclude] 

Diese Lösung hat den zusätzlichen Vorteil, dass result auch in einem Generator und die Ergebnisliste gedreht werden konnte braucht nicht explizit konstruiert werden.

Verwandte Themen