Naprawdę szaleję z tego powodu i już spędziłem nieproporcjonalną ilość czasu, próbując dowiedzieć się, co się tutaj dzieje. Więc proszę, pomóż mi =)
Muszę zrobić dopasowanie RegExp ciągów w JavaScript. Niestety zachowuje się bardzo dziwnie. Ten kod:
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>");
}
}
Zwraca „kot” i „pies” dla pierwszych dwóch elementów, tak jak powinno, ale potem exec()
zaczynają wracać niektóre wywołania null
. Nie rozumiem dlaczego.
Umieściłem tutaj Fiddle , gdzie możesz uruchomić i edytować kod.
Do tej pory próbowałem tego w Chrome i Firefox.
Twoje zdrowie!
/ Christofer
javascript
regex
cpak
źródło
źródło
"I have a cat and a dog too."
, jak się wydajeOdpowiedzi:
Och, oto jest. Ponieważ definiujesz swoje wyrażenie regularne globalne, dopasowuje się ono najpierw
cat
i przy drugim przebiegu pętlidog
. Więc w zasadzie wystarczy zresetować swoje wyrażenie regularne (jest to wewnętrzny wskaźnik). Por. to: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); }
źródło
Obiekt regex ma właściwość,
lastIndex
która jest aktualizowana podczas uruchamianiaexec
. Więc kiedy wykonujesz wyrażenie regularne na np. „Mam kota i psa też.”,lastIndex
Jest ustawione na 12. Następnym razem, gdy uruchomiszexec
ten sam obiekt wyrażenia regularnego, zacznie on szukać od indeksu 12. Więc musisz zresetowaćlastIndex
właściwość między każdym biegiem.źródło
myRe.lastIndex = 0;
do późniejszego użytku.Dwie rzeczy:
g
flagi (globalnej). Aby rozwiązać ten problem, polecam po prostu przypisać0
dolastIndex
członkaRegExp
obiektu. Ma to lepszą wydajność niż niszcz i odtwarzaj.in
słowa kluczowego do chodzenia poArray
obiekcie, ponieważ może to prowadzić do nieoczekiwanych wyników w przypadku niektórych bibliotek. Czasami powinieneś sprawdzić coś takiego jakisNaN(i)
, lub jeśli wiesz, że nie ma dziur, użyj klasycznej pętli for.Kod może być:
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>"); } }
źródło
rx.lastIndex = 0
jest znacznie lepsze niż ponowne tworzenie obiektu RegEx wewnątrz pętli.Miałem podobny problem używając tylko / g, a proponowane tutaj rozwiązanie nie działało u mnie w FireFox 3.6.8. Mam mój scenariusz
var myRegex = new RegExp("my string", "g");
Dodam to na wypadek, gdyby ktoś inny miał ten sam problem, co w przypadku powyższego rozwiązania.
źródło