2016-04-13 2 views
0

Ich habe eine einfache regulären Ausdruck (in C# verwendet):Wie lässt sich der reguläre Ausdruck nicht zu viele Schritte machen?

\becua(?:[a-zA-ZáéíóúñÑÑäëïöü])*\b(.(?!embajada))*\s+embajada 

1) Wörter mit "ecua"
2) ausgehend Was auch immer das nach diesem
3) Das Wort "embajada" danach kommt " was auch immer "

Aber es macht zu viele Schritte, wie kann ich das verhindern? Ich möchte nur, dass es die Charaktere übergibt, bis es das Wort "embajada" findet und nicht bei jedem einzelnen Zeichen rückwärts läuft. Dies scheint einfacher regulärer Ausdruck, aber wenn ich einen größeren Text verwenden wirft es einen katastrophalen Rückzieher (oder Timeout), wenn das Muster

nicht

Beispiel: https://regex101.com/r/tQ7mM9/4

Vielen Dank im Voraus

+0

Sie verwenden müssen '(? = Embajada)' statt '(?! Embajada) ', ich denke – rock321987

+0

Es gibt kein Wort" embajada "in Ihrem Text, dort ist nur" gembajada ". –

+0

Ich würde es aufrollen: https://regex101.com/r/iR5eW3/1 –

Antwort

1

Sie Ihr Muster in einem gierigen Art und Weise schreiben kann, aber dieses Mal umschließt alle Teile mit Quantifizierern in einer Atomgruppe. Tun müssen, das Sie offensichtlich Test mit einem Look-Ahead machen, aber die Auswirkungen von zu viel Tests zu begrenzen, können Sie die Regex-Engine unter Verwendung von Zeichenklassen helfen ([^e] hier) nur Tests an interessanten Positionen durchführen:

\becua(?>\w*[^e]*(?:\Be[^e]*|e(?!mbajada\b)[^e]*)*)embajada 

Details:

\becua 
(?> 
    \w*  # last part of "ecua..." 

    [^e]* # all that is not an "e" 
    (?: 
     \Be   # an "e" not at the start of a word 
     [^e]* 
     | 
     e(?!mbajada\b) # an "e" that is not the start of "embajada" 
     [^e]* 
    )*  # repeat as possible 
) # close the atomic group (backtracking is no more possible) 
embajada 

When the pattern fails
When the pattern succeeds

Jetzt ein nicht gieriger Ansatz (gleiche Idee, die Auswirkungen des nicht-gierigen Quantor zu begrenzen):

\becua(?>e*[^e]+)*?\bembajada\b 

When the pattern fails
When the pattern succeeds

+0

Eine Bemerkung: die '\ w' wird' _' und Ziffern entsprechen, denke ich '\ p {L}' ist ein besserer Ersatz für '[a-zA-ZáéíóúñÑÑääïöü]'. –

+0

Danke Bro !! Es klappt!! Ich wähle die zweite Regex, weil es einfacher zu implementieren ist (Ich muss Schlüsselwörter, die von Benutzern eingefügt wurden, in reguläre Ausdrücke konvertieren). – Crabax

0

Ist das, was Sie suchen zum? \b(ecua\w+) .*? (embajada)

+0

Die schlechteste Antwort bekam alle Upvotes. –

+1

Das funktioniert, macht aber 117k Schritte im Falle eines Fehlers, ein Benutzer hat eine Regex kommentiert, die 66k Schritte in demselben Fall macht – Crabax

0

-Test durchgeführt, auf regex101

Die untenstehende Tabelle der Vergleich verschiedener Methoden ist. Der erste ist meins, der zweite ist modifiziert OP'sregex, der dritte ist eine modifizierte Version der Antwort von einem anderen Benutzer hier gegeben und der vierte ist von Wiktor. Erfolglos-Spiele sind für Fehler von embajada zu embajad

+------+--------+--------+--------+--------+-------+------+--------------+ 
|    Regex      | Successful | Unsuccessful | 
+------+--------+--------+--------+--------+-------+------+--------------+ 
| \becua.*embajada       | 310 steps | 167543 steps | 

| \becua(?:.*)\b(.(?=embajada))*embajada | 993 steps | 579122 steps | 

| \becua.*?embajada      | 23897 steps | 167543 steps | 

| (?>\becua\p{L}*\b\s*\S*) 
| (?>(?:\s+(?!embajada)\S*)*)\s+embajada | 18001 steps | 111394 steps | 
+------+--------+--------+--------+--------+-------+------+--------------+ 

1. Regex scheint in der geringsten Anzahl von Maßnahmen zu ergreifen, sowohl erfolgreiche und erfolglose Begegnungen

+1

Sie versuchen meine Muster aus Kommentaren :)? Nett. Bessere Tests von http://regexhero.net/tester. Mein letztes '(?> \ Becua \ p {L} * \ b \ s * \ S *) (?> (?: \ S + (?! embajada) \ S *) *) \ s + embajada' zeigt 78, 2 Iterationen pro Sekunde. –

+0

@ WiktorStribiżew wird bald aktualisiert – rock321987

+1

Siehe Casimirs Antwort, studieren Sie dieses Muster. Drei mal schneller als meins. –

Verwandte Themen