Na czym polega problem z tym wyrażeniem regularnym, gdy używam flagi globalnej i flagi bez rozróżniania wielkości liter? Zapytanie to dane wejściowe generowane przez użytkownika. Wynik powinien być [prawda, prawda].
var query = 'Foo B';
var re = new RegExp(query, 'gi');
var result = [];
result.push(re.test('Foo Bar'));
result.push(re.test('Foo Bar'));
// result will be [true, false]
var reg = /^a$/g;
for(i = 0; i++ < 10;)
console.log(reg.test("a"));
re
.Odpowiedzi:
RegExp
Obiekt śledzilastIndex
gdzie wystąpił mecz, więc w kolejnych meczach będzie zacząć od ostatniego indeksu używane zamiast 0. Spójrz:Jeśli nie chcesz ręcznie resetować
lastIndex
do 0 po każdym teście, po prostu usuńg
flagę.Oto algorytm, który dyktują specyfikacje (sekcja 15.10.6.2):
źródło
lastIndex
znajduje się w krokach 5, 6 i 11. Twoje oświadczenie otwierające jest prawdziwe, JEŚLI GLOBALNA FLAGA JEST USTAWIONA.Używasz jednego
RegExp
obiektu i wykonujesz go wiele razy. Przy każdym kolejnym wykonaniu jest kontynuowany od indeksu ostatniego dopasowania.Musisz „zresetować” wyrażenie regularne, aby rozpocząć od początku przed każdym wykonaniem:
Powiedziawszy, że może być bardziej czytelne tworzenie nowego obiektu RegExp za każdym razem (obciążenie jest minimalne, ponieważ RegExp jest buforowany i tak):
źródło
g
flagi.RegExp.prototype.test
aktualizuje właściwość wyrażeń regularnych,lastIndex
aby każdy test rozpoczął się w miejscu, w którym zatrzymał się ostatni. Sugeruję użycie,String.prototype.match
ponieważ nie aktualizujelastIndex
właściwości:Uwaga:
!!
konwertuje go na wartość logiczną, a następnie odwraca wartość logiczną, aby odzwierciedlała wynik.Alternatywnie możesz po prostu zresetować
lastIndex
właściwość:źródło
Usunięcie
g
flagi globalnej rozwiąże problem.Powinien być
źródło
Musisz ustawić re.lastIndex = 0, ponieważ przy regexie flagi g śledź ostatnie wystąpienie dopasowania, więc test nie przejdzie do testowania tego samego ciągu, w tym celu musisz zrobić re.lastIndex = 0
źródło
Użycie flagi / g nakazuje kontynuowanie wyszukiwania po trafieniu.
Jeśli dopasowanie się powiedzie, metoda exec () zwraca tablicę i aktualizuje właściwości obiektu wyrażenia regularnego.
Przed pierwszym wyszukiwaniem:
Po pierwszym wyszukiwaniu
Usuń g i wyjdzie z wyszukiwania po każdym wywołaniu exec ().
źródło
exec
.Miałem funkcję:
Pierwsze połączenie działa. Drugie połączenie nie.
slice
Operacja narzeka wartości zerowej. Zakładam, że dzieje się tak z powodure.lastIndex
. Jest to dziwne, ponieważ oczekiwałbym, że nowaRegExp
będzie przydzielana za każdym razem, gdy funkcja jest wywoływana, a nie współużytkowana przez wiele wywołań mojej funkcji.Kiedy zmieniłem na:
Wtedy nie dostaję
lastIndex
efektu zatrzymania. Działa tak, jak bym tego oczekiwał.źródło