RegExp.exec() gibt sporadisch NULL zurück

Lesezeit: 6 Minuten

Benutzer-Avatar
cpak

Ich werde ernsthaft verrückt deswegen und ich habe bereits unverhältnismäßig viel Zeit damit verbracht, herauszufinden, was hier vor sich geht. Also hilf mir bitte =)

Ich muss einen RegExp-Abgleich von Zeichenfolgen in JavaScript durchführen. Leider verhält es sich sehr merkwürdig. Dieser Code:

var rx = /(cat|dog)/gi;
var w = new Array("I have a cat and a dog too.", "There once was a dog and a cat.", "I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.");

for (var i in w) {
    var m = null;
    m = rx.exec(w[i]);
    if(m){
        document.writeln("<pre>" + i + "\nINPUT: " + w[i] + "\nMATCHES: " + m.slice(1) + "</pre>");
    }else{
        document.writeln("<pre>" + i + "\n'" + w[i] + "' FAILED.</pre>");
    }
}

Gibt “Katze” und “Hund” für die ersten beiden Elemente zurück, wie es sein sollte, aber dann einige exec()-Anrufe beginnen zurückzukehren null. Ich verstehe nicht warum.

Ich habe eine Geige gepostet hierwo Sie den Code ausführen und bearbeiten können.

Und bisher habe ich das in Chrome und Firefox versucht.

  • es schlägt nur auf a fehl "I have a cat and a dog too."es scheint

    – SilentGhost

    18. Januar 2011 um 13:48 Uhr

  • exec gibt null zurück, wenn eine Übereinstimmung absichtlich fehlschlägt, sodass sie aus irgendeinem Grund nicht übereinstimmt.

    – Martin Jespersen

    18. Januar 2011 um 13:49 Uhr

Oh, hier ist es. Da Sie Ihren regulären Ausdruck global definieren, passt er zuerst catund beim zweiten Durchlauf der Schleife dog. Im Grunde müssen Sie also auch nur Ihre Regex (ihren internen Zeiger) zurücksetzen. Vgl. Dies:

var w = new Array("I have a cat and a dog too.", "I have a cat and a dog too.", "I have a cat and a dog too.", "I have a cat and a dog too.");

for (var i in w) {
    var rx = /(cat|dog)/gi;
    var m = null;
    m = rx.exec(w[i]);
    if(m){
        document.writeln("<p>" + i + "<br/>INPUT: " + w[i] + "<br/>MATCHES: " + w[i].length + "</p>");
    }else{
        document.writeln("<p><b>" + i + "<br/>'" + w[i] + "' FAILED.</b><br/>" + w[i].length + "</p>");
    }
    document.writeln(m);
}

  • Woh– “interner Zeiger einer Regex”? Könnten Sie eine Ressource dazu empfehlen? Vielen Dank!

    – Katerlouis

    14. Januar 2019 um 15:00 Uhr

  • Whoa… Ich habe in den letzten 14 Jahren intensiv JavaScript geschrieben, und RexExps immer intensiver in den letzten 8 Jahren — und das haut mich ziemlich um. Würde ich das besser verstehen, wenn ich besser in Perl wäre?

    – Codi

    20. Oktober 2021 um 2:14 Uhr

  • Ich würde dir 1000 Stimmen geben, wenn ich könnte. Das hat mir gerade Stunden gespart und mich umgehauen.

    – Steinroe

    1. April um 8:47

Das Regex-Objekt hat eine Eigenschaft lastIndex die aktualisiert wird, wenn Sie laufen exec. Wenn Sie also den regulären Ausdruck ausführen, z. B. “Ich habe auch eine Katze und einen Hund.”, lastIndex auf 12 eingestellt ist. Das nächste Mal, wenn Sie laufen exec Bei demselben Regex-Objekt beginnt es mit der Suche ab Index 12. Sie müssen also die zurücksetzen lastIndex Eigenschaft zwischen jedem Lauf.

  • Danke für die Erklärung! Es hilft sehr beim Einstellen myRe.lastIndex = 0; für die spätere Verwendung.

    – Antonius

    20. Januar 2013 um 1:52 Uhr

  • Ich denke, dies sollte die richtige Antwort sein, da es der bewährten Methode folgt, dasselbe Regex-Objekt wiederzuverwenden

    – smurtagh

    18. März 2019 um 20:17 Uhr


  • Stimmen Sie zu, dies sollte die richtige Antwort sein. Es verwendet dasselbe Regex-Objekt wieder und erklärt auch die interne Mechanik. OP sollte einen Wechsel in Betracht ziehen.

    – SeanColey

    16. Dezember 2019 um 16:30 Uhr

Zwei Dinge:

  1. Der erwähnte Bedarf an zurücksetzen bei der Verwendung der g (globale) Flagge. Um dies zu lösen, empfehle ich einfach zuzuweisen 0 zum lastIndex Mitglied von RegExp Objekt. Dies hat eine bessere Leistung als Zerstören und Wiederherstellen.
  2. Seien Sie vorsichtig, wenn verwenden in Schlüsselwort, um an zu gehen Array -Objekt, da dies bei einigen Bibliotheken zu unerwarteten Ergebnissen führen kann. Manchmal sollten Sie mit etwas wie überprüfen isNaN(i)oder wenn Sie wissen, dass es keine Löcher hat, verwenden Sie die klassische for-Schleife.

Der Code kann sein:

var rx = /(cat|dog)/gi;
w = ["I have a cat and a dog too.", "There once was a dog and a cat.", "I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat."];

for (var i in w)
 if(!isNaN(i))        // Optional, check it is an element if Array could have some odd members.
  {
   var m = null;
   m = rx.exec(w[i]); // Run
   rx.lastIndex = 0;  // Reset
   if(m)
    {
     document.writeln("<pre>" + i + "\nINPUT: " + w[i] + "\nMATCHES: " + m.slice(1) + "</pre>");
    } else {
     document.writeln("<pre>" + i + "\n'" + w[i] + "' FAILED.</pre>");
    }
  }

  • Dies sollte die richtige Antwort sein. Einstellung rx.lastIndex = 0 ist viel besser, als das RegEx-Objekt innerhalb der Schleife neu zu erstellen.

    – Minoru

    25. September 2019 um 19:27 Uhr

  • Trotzdem wäre es besser, den einfach nicht zu verwenden g kennzeichnen, wenn Sie es nicht wollen. Es macht keinen Sinn, eine Regex zu erstellen, die speziell aktualisiert wird lastIndex nur um es nach jeder Ausführung zurückzusetzen.

    – Robert

    8. August 2021 um 19:44 Uhr


  • Möglicherweise möchten Sie global in einem Element suchen und dann die Regex für das nächste Element zurücksetzen und wiederverwenden. Ich denke, OP-Code ist nur ein Beispiel, um zu zeigen, was nicht verstanden wird.

    – ESL

    3. September 2021 um 19:16 Uhr

Ich hatte ein ähnliches Problem nur mit /g, und die hier vorgeschlagene Lösung funktionierte bei mir in FireFox 3.6.8 nicht. Ich habe mein Skript zum Laufen gebracht

var myRegex = new RegExp("my string", "g");

Ich füge dies hinzu, falls jemand anderes das gleiche Problem hat, das ich mit der obigen Lösung hatte.

1205960cookie-checkRegExp.exec() gibt sporadisch NULL zurück

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy