2013-12-10 22 views
8

Mit Regex wie kann man alles in einer Zeichenfolge, die nicht etwas ist? Dies macht vielleicht keinen Sinn, aber lesen Sie weiter.Spiel alles, was etwas ist?

nehmen also das Wort baby zum Beispiel alles passen, dass nicht ist ein b Sie so etwas wie [^b] tun würde, und dies würde a und y entspricht. Einfach genug! Aber wie in dieser Zeichenfolge Ben sits on a bench kann ich alles, was nicht ben übereinstimmen, so würde ich versuchen, sits on a ch übereinstimmen?

Besser noch passen alles, was kein Muster ist? z.B. in 1a2be3 übereinstimmen alles, was nicht number,letter,number ist, so würde es jede Kombination in der Zeichenfolge außer 1a2 übereinstimmen?

+6

Es klingt wie Sie können einfach eine Regex ersetzen Sie Ihre Blacklisted Muster mit der leeren Zeichenfolge und sehen, ob etwas bleibt? – Jon

+0

Können Sie mit einem Beispiel antworten? – Srb1313711

+1

@ Srb1313711 Jede Programmiersprache der Wahl? Ich bin mir nicht sicher, ob das Ersetzen in einer Regex allein erfolgen kann. – skiwi

Antwort

0

Wenn Sie alle Wörter außer einem übereinstimmen möchten, können Sie negative Lookahead verwenden: \b(?!ben\b)\w*\b, aber für eine Antwort auf Ihre genaue Frage scheint Jons Kommentar am einfachsten.

+0

Das hat nicht funktioniert für mich Ich testete hier http://gskinner.com/RegExr/ mit meinem Ben Beispiel und es passte nur die erste Ben? Kannst du auch das \ b erklären? – Srb1313711

+0

\ b ist Wortgrenze, versuchen Sie es hier: http://regexpal.com/ funktioniert gut für mich (obwohl nicht genau das, was Sie angefordert haben, da es Wörter entspricht). – hillel

1
(?:ben)|(.) 

Was regex tut, ist Spiel ben oder jedes andere Zeichen, jedoch ist ben nicht erfasst, aber die anderen Charaktere sind. Sie werden also viele Matches haben, mit Ausnahme der ben. Dann können Sie alle diese Übereinstimmungen zusammenfügen, um die Zeichenfolge ohne die ben 's zu erhalten.

Hier ein Beispiel in Python.

import re 

thestr = "Ben sits on a bench" 
regex = r'(?:ben)|(.)' 

matches = re.findall(regex, thestr, re.IGNORECASE) 
print ''.join(matches) 

Dies wird ouput:

sits on a ch 

Hinweis der führende Raum. Sie können das natürlich loswerden, indem Sie .strip() hinzufügen.

Beachten Sie auch, dass es wahrscheinlich schneller ist, eine Regex zu erstellen, die ben durch eine leere Zeichenfolge ersetzt, um das gleiche Ergebnis zu erhalten. Aber wenn Sie diese Technik in einem komplexeren Regex verwenden möchten, könnte es sich als nützlich erweisen.

Und natürlich können Sie auch setzen komplexere reguläre Ausdrücke am Ort der ben, so zum Beispiel Ihres number,letter,number Beispiel wäre:

(?:[0-9][a-z][0-9])|(.) 
+0

@ Srb1313711 hat diese Lösung für Sie funktioniert? – rednaw

+0

Können Sie ein '*' setzen, um alles andere zu entsprechen, anstatt * char mit char * zu vergleichen und '.join' zu verwenden? – ADTC

+0

Wenn Sie '. *' Verwenden würden, könnte es mit jedem 'ben's übereinstimmen, also können Sie das nicht tun. – rednaw

0

Okay Das einfachste, was zu tun Spiel Alles ist

(.*?) 

Dann auf das Muster passen ein anderes Match für Was Sie nicht wollen (für zB in Perl haben Sie das Muster in der Variablen $ & übereinstimmen).

Wenn es übereinstimmt, Das ist nicht, was Sie wollen, sonst haben Sie Ihre Übereinstimmung.

Einfache A-B, wo A ist alles (. *?) Und B ist was Sie nicht wollen.So Sie am Ende tun zwei Übereinstimmungen, aber ich denke, das ist in Ordnung.

0

Ersetzen Sie einfach alles, was entspricht Ihr Muster mit einem Leerzeichen (um es zu löschen).

Sie haben nicht angegeben, welche Sprache Sie verwenden, so genetisch:

s/ben//g 

und Ihr anderes Beispiel:

s/\d[a-zA-Z]\d//g 
+0

Ich suche, um nicht zu ersetzen, kann dies funktionieren, aber nicht was ich suche, aber danke für die Antwort! – Srb1313711

0

Wenn Sie Liste von Strings möchten, verwenden Sie "split auf regexp" statt "Match auf Regexp".

1

Kurze Antwort: Sie können nicht tun, was Sie fragen. Technisch hat der erste Teil eine hässliche Antwort, aber der zweite Teil (wie ich es verstehe) hat keine Antwort.


Für Ihren ersten Teil habe ich eine ziemlich unpraktische (noch pure Regex) Antwort; etwas Besseres würde Code erfordern (wie @ rednaws viel sauberere Antwort oben). Ich fügte dem Test hinzu, um es umfassender zu machen. (Der Einfachheit halber verwende ich grep -Pio für PCRE, Groß- und Kleinschreibung, Druck ein Spiel pro Zeile.)

$ echo "Ben sits on a bench better end" \ 
    |grep -Pio '(?=b(?!en)|(?<!b)en|e(?!n)|(?<!be)n|[^ben])\w+' 
sits 
on 
a 
ch 
better 
end 

Ich bin im Grunde ein Sonderfall für jeden Buchstaben in „ben“ zu machen, damit ich nur Iterationen umfassen kann die nicht selbst Teil der Zeichenfolge "ben" sind. Wie gesagt, nicht wirklich praktisch, auch wenn ich technisch deine Frage beantworte. Ich habe auch a blow-by-blow explanation of this regex gespeichert, wenn Sie weitere Details wünschen.

Wenn Sie gezwungen sind, eine reine Regex anstelle von Code zu verwenden, ist Ihre beste Wette für solche Artikel, Code in zu schreiben generieren die Regex. Auf diese Weise können Sie eine saubere Kopie davon behalten.


Ich bin mir nicht sicher, was Sie für den Rest Ihrer Herausforderung fragen; ein regulärer Ausdruck ist entweder gierig oder faul [1][2], und ich weiß nicht von irgendwelchen Implementierungen, die „jede Kombination“ und nicht nur die erste Kombination von beiden Verfahren finden können. Wenn es so etwas gäbe, wäre es im wirklichen Leben sehr langsam (eher als schnelle Beispiele); Die langsame Geschwindigkeit von Regex-Engines wäre nicht hinnehmbar, wenn sie gezwungen wären, jede Möglichkeit zu prüfen, die im Grunde genommen eine ReDoS wäre.

Beispiele:

# greedy evaluation (default) 
$ echo 1a2be3 |grep -Pio '(?!\d[a-z]\d)\w+' 
a2be3 

# lazy evaluation 
$ echo 1a2be3 |grep -Pio '(?!\d[a-z]\d)\w+?' 
a 
2 
b 
e 
3 

Ich nehme an, Sie suchen 11aaa2a2ba2bea2be322b2be2be3bbebe3ee33 aber ich glaube nicht, dass Sie mit einer reinen Regex bekommen . Du benötigst etwas Code, um jede Teilzeichenkette zu generieren, und dann kannst du eine Regex verwenden, um das verbotene Muster herauszufiltern (wieder geht es hier um gierige vs faul vs ReDoS).

+0

+1 Vielen Dank für eine sehr detaillierte Antwort, die diese Zeit brauchte, um zu schreiben und obwohl sie die Frage nicht beantworten konnte, war sie immer noch sehr hilfreich. – Srb1313711

Verwandte Themen