webentwicklung-frage-antwort-db.com.de

Regulärer Ausdruck, der keine bestimmte Zeichenfolge enthält

Ich habe so etwas

aabbabcaabda

zum Auswählen einer minimalen Gruppe, die von a umhüllt wird. Ich habe diese /a([^a]*)a/, die gut funktioniert

Aber ich habe ein Problem mit Gruppen, die mit aa umbrochen wurden, wobei ich etwas wie /aa([^aa]*)aa/ brauche, das nicht funktioniert, und ich kann das erste wie /aa([^a]*)aa/, weil es beim ersten Auftreten von a enden würde, was ich nicht will.

Im Allgemeinen gibt es eine Möglichkeit, wie man sagt enthält keine Zeichenfolge in der gleichen Weise, wie ich sagen kann enthält kein Zeichen mit [^a]?

Einfach gesagt, ich brauche aa gefolgt von einem beliebigen Zeichen außer der Sequenz aa und endet dann mit aa

76
Jakub Arnold

Im Allgemeinen ist es mühsam, einen regulären Ausdruck zu schreiben, der keine bestimmte Zeichenfolge enthält . Wir mussten dies für Berechnungsmodelle tun - Sie nehmen eine NFA, die leicht zu definieren ist, und reduzieren sie dann auf einen regulären Ausdruck. Der Ausdruck für Dinge, die nicht "cat" enthalten, war ungefähr 80 Zeichen lang.

Edit: Ich bin gerade fertig und ja, es ist:

aa([^a] | a[^a])aa

hier ist ein sehr kurzes Tutorial. Ich habe einige großartige gefunden, aber ich kann sie nicht mehr sehen.

18
Claudiu

Durch die Kraft von Google habe ich einen Blogpost aus 2007 gefunden, der den folgenden regulären Ausdruck ergibt, der mit einem String übereinstimmt, der kein enthält bestimmter Teilstring:

^((?!my string).)*$

Es funktioniert wie folgt: Es sucht nach null oder mehr (*) Zeichen (.), Die nicht mit Ihrer Zeichenfolge beginnen (?! - negativer Lookahead), und es legt fest, dass die gesamte Zeichenfolge aus solchen Zeichen bestehen muss (mithilfe des ^ und $ anker). Oder anders ausgedrückt:

Die gesamte Zeichenfolge muss aus Zeichen bestehen, die nicht mit einer bestimmten Zeichenfolge beginnen. Dies bedeutet, dass die Zeichenfolge die angegebene Teilzeichenfolge nicht enthält.

202
Grey Panther

Alles, was Sie brauchen, ist ein widerstrebender Quantifizierer:

regex: /aa.*?aa/

aabbabcaabda   => aabbabcaa

aaaaaabda      => aaaa

aabbabcaabda   => aabbabcaa

aababaaaabdaa  => aababaa, aabdaa

Sie können auch einen negativen Lookahead verwenden, aber in diesem Fall ist dies nur eine ausführlichere Methode, um dasselbe zu erreichen. Außerdem ist es ein bisschen kniffliger, als Gpojd es sich vorgestellt hat. Der Lookahead muss an jeder Position angewendet werden, bevor der Punkt das nächste Zeichen aufnehmen darf.

/aa(?:(?!aa).)*aa/

Der von Claudiu und Finnw vorgeschlagene Ansatz funktioniert, wenn die Sentinel-Zeichenfolge nur zwei Zeichen lang ist, aber (wie Claudiu eingeräumt hat) für längere Zeichenfolgen zu unhandlich.

10
Alan Moore
/aa([^a]|a[^a])*aa/
7
finnw

Ich bin mir nicht sicher, ob es sich um ein Standardkonstrukt handelt, aber ich denke, Sie sollten einen Blick auf "negative lookahead" werfen (die lautet: "?!", Ohne die Anführungszeichen). Es ist viel einfacher als alle Antworten in diesem Thread, einschließlich der akzeptierten.

Beispiel: Regex: "^ (?! 123) [0-9] *\w" Erfasst alle Zeichenfolgen, die mit Ziffern gefolgt von Buchstaben beginnen, AUSSER, wenn "diese Ziffern" 123 sind.

http://msdn.Microsoft.com/en-us/library/az24scfc%28v=vs.110%29.aspx#grouping_constructs (Microsoft-Seite, aber ziemlich umfassend) für lookahead/lookbehind

PS: es funktioniert gut bei mir (.Net). Aber wenn ich etwas falsch mache, lass es uns bitte wissen. Ich finde dieses Konstrukt sehr einfach und effektiv, daher bin ich von der akzeptierten Antwort überrascht.

6
AFract

Ich musste den folgenden Code ersetzen, indem ich einen GET-Parameter zu allen Verweisen auf JS-Dateien außer einem hinzufügte.

<link rel="stylesheet" type="text/css" href="/login/css/ABC.css" />
<script type="text/javascript" language="javascript" src="/localization/DEF.js"></script>
<script type="text/javascript" language="javascript" src="/login/jslib/GHI.js"></script>
<script type="text/javascript" language="javascript" src="/login/jslib/md5.js"></script>
sendRequest('/application/srvc/EXCEPTION.js', handleChallengeResponse, null);
sendRequest('/application/srvc/EXCEPTION.js",handleChallengeResponse, null);

Dies ist der verwendete Matcher:

(?<!EXCEPTION)(\.js)

Suchen Sie nach allen Vorkommen von ".js", und verwerfen Sie das Ergebnis aus dem Ergebnis-Array, wenn die Zeichenfolge "EXCEPTION" vorangestellt ist. Das nennt man negatives Aussehen. Da ich einen Tag damit verbracht habe, herauszufinden, wie das geht, dachte ich, ich sollte es teilen.

4
jsaddwater
".*[^(\\.inc)]\\.ftl$"

In Java findet man alle Dateien, die mit ".ftl" enden, aber nicht mit ".inc.ftl" enden, was genau das ist, was ich wollte.

2
twopigs