2009-09-08 10 views
74

Kann ein regulärer Ausdruck verwendet werden, um eine beliebige Zeichenfolge außer einer bestimmten Zeichenkettenkonstanten zu finden, sagen wir "ABC"? Ist es möglich, nur eine bestimmte String-Konstante auszuschließen? Vielen Dank im Voraus.RegEx zum Ausschließen einer bestimmten Zeichenkettenkonstante

+1

Welches Werkzeug sind benutzen? Je nach Tool gibt es möglicherweise eine Möglichkeit, dies extern für Ihre Regex anzugeben. grep unterstützt zum Beispiel die Option -v, um den Sinn der Übereinstimmung zu invertieren. –

+1

Kannst du nicht 'If (/^ABC $ /) else {...} wo die andere wäre die nicht passende ABC – Xetius

+0

So suchen Sie nach jedem Zeichen einer gegebenen Zeichenfolge, mit Ausnahme der ABC-Teil davon ? Mit anderen Worten, "Ein String mit ABC" würde "A String mit" entsprechen. –

Antwort

4

Dies ist nicht einfach, es sei denn, Ihre Regexp-Engine hat spezielle Unterstützung dafür. Der einfachste Weg, um eine Negativ-Spiel-Option, zum Beispiel zu verwenden wäre:

$var !~ /^foo$/ 
    or die "too much foo"; 

Wenn nicht, Sie haben etwas Böses zu tun:

$var =~ /^(($)|([^f].*)|(f[^o].*)|(fo[^o].*)|(foo.+))$/ 
    or die "too much foo"; 

Dass man im Grunde sagt, „wenn es mit nicht startet - f, der Rest kann alles sein, wenn es mit f, nicht o beginnt, kann der Rest alles sein; andernfalls, wenn es fo startet, sollte das nächste Zeichen besser kein anderes sein o ".

+0

Das erlaubt nicht die leeren Zeichenfolgen 'f',' fo' und 'foo'. – Gumbo

+0

@Gumbo: Es erlaubt die leere Zeichenfolge ganz gut; Beachten Sie, dass ($) die erste Alternative ist, also wird^$ (leere Zeichenfolge) akzeptiert. Ich habe es getestet, und zumindest in Perl 5.0.10 wird der leere String akzeptiert. – derobert

+0

... sorry, perl 5.10.0, natürlich! – derobert

93

Sie müssen eine negative Lookahead Assertion verwenden.

(?!^ABC$) 

Sie könnten zum Beispiel Folgendes verwenden.

(?!^ABC$)(^.*$) 

Wenn dies in Ihrem Editor nicht funktioniert, versuchen Sie dies. Es wird geprüft, in Ruby und JavaScript zu arbeiten:

^((?!ABC).)*$ 
+1

Dies funktioniert, wenn Sie nach einer Zeichenfolge suchen, die ABC nicht enthält. Aber ist das das Ziel? Oder ist das Ziel, jedem Charakter außer ABC zu entsprechen? –

+0

Danke, dass du das unterstrichen hast, du hast Recht - mein Vorschlag vermeidet nur Strings, die mit ABC beginnen - ich habe vergessen, die Behauptung zu verankern. Ich werde das korrigieren. –

+0

Das ist immer noch anders als das, was ich dachte. Vielleicht wird der Fragesteller klären, wonach sie suchen. –

3

Sie negative Vorschau verwenden könnte, oder so etwas wie folgt aus:

^([^A]|A([^B]|B([^C]|$)|$)|$).*$ 

Vielleicht könnte es ein wenig vereinfacht werden.

3

In .NET können Sie zu Ihrem Vorteil wie folgt verwenden Gruppierung:

http://regexhero.net/tester/?id=65b32601-2326-4ece-912b-6dcefd883f31

Sie werden bemerken, dass:

(ABC)|(.) 

alles außer ABC in der zweiten Gruppe greifen wird. Klammern umgeben jede Gruppe. So (ABC) ist Gruppe 1 und Gruppe 2.

Also nur Sie die zweite Gruppe wie diese greifen in einem ersetzen (.):

$2 

Oder in .NET Blick auf die Gruppen Sammlung innerhalb der Regex-Klasse für ein wenig mehr Kontrolle.

Sie sollten in den meisten anderen Regex-Implementierungen etwas Ähnliches tun können.

UPDATE: Ich habe einen viel schnelleren Weg gefunden, dies zu tun hier: http://regexhero.net/tester/?id=997ce4a2-878c-41f2-9d28-34e0c5080e03

Er verwendet immer noch die Gruppierung (ich einen Weg nicht finden kann, die nicht Gruppierung nicht verwendet). Aber diese Methode ist über 10X schneller als die erste.

2

diesem regulären Ausdruck Versuchen:

^(.{0,2}|([^A]..|A[^B].|AB[^C])|.{4,})$ 

Es beschreibt drei Fälle:

  1. weniger als drei beliebige Zeichen
  2. genau drei Zeichen, während entweder
    • die erste nicht ist A oder
    • die erste ist A aber die zweite ist nicht B oder
    • die erste ist A, die zweite B aber das dritte ist, dass Sie nicht C
  3. mehr als drei beliebige Zeichen
Verwandte Themen