2011-07-18 8 views
10

Zmagałem się z tym przez cały dzień i nie mogę się dowiedzieć, czy robię coś źle, czy też znalazłem błąd w silniku JavaScript Chrome . Wygląda na to, że kolejne wywołania do obiektu RegExp z flagą globalną zwracają niespójne wyniki dla tego samego ciągu wejściowego. Ja badania z następujących funkcji:Kolejne wywołania testu RegExp kończą się niepowodzeniem w przypadku wzorca z globalną opcją

function testRegex(pattern, array) { 
    document.writeln('Pattern = ' + pattern + ', Array = ' + array + '<br/>'); 
    for (var ii = 0; ii < array.length; ii++) { 
     document.writeln(ii + ', '); 
     document.writeln(array[ii] + ', '); 
     document.writeln(pattern.test(array[ii]) + '<br />'); 
    } 
    document.writeln('<br/>'); 
} 

Kiedy wywołać funkcję z /a/g jako wzór i różnych tablic ciągów, mam następujące wyniki, z których wiele jest nieprawidłowy miarę mogę powiedzieć:

// EXPECTED: True 
// ACTUAL: True 
testRegex(/a/g, ['a']); 

// EXPECTED: True, True 
// ACTUAL: True, False 
testRegex(/a/g, ['a', 'a']); 

// EXPECTED: True, True, True 
// ACTUAL: True, False, True 
testRegex(/a/g, ['a', 'a', 'a']); 

// EXPECTED: True, False, True 
// ACTUAL: True, False, True 
testRegex(/a/g, ['a', 'b', 'a']); 

// EXPECTED: True, True, True, True 
// ACTUAL: True, False, True, False 
testRegex(/a/g, ['a', 'a', 'a', 'a']); 

// EXPECTED: True, False, False, True 
// ACTUAL: True, False, False, True 
testRegex(/a/g, ['a', 'b', 'b', 'a']); 

Kiedy nazywają tę samą funkcję z tych samych tablic ciągów, ale przechodzą /a/ jako wzór, rzeczywiste rezultaty wszystkie pasujące oczekiwanych rezultatów.

// EXPECTED: True 
// ACTUAL: True 
testRegex(/a/, ['a']); 

// EXPECTED: True, True 
// ACTUAL: True, True 
testRegex(/a/, ['a', 'a']); 

// EXPECTED: True, True, True 
// ACTUAL: True, True, True 
testRegex(/a/, ['a', 'a', 'a']); 

// EXPECTED: True, False, True 
// ACTUAL: True, False, True 
testRegex(/a/, ['a', 'b', 'a']); 

// EXPECTED: True, True, True, True 
// ACTUAL: True, True, True, True 
testRegex(/a/, ['a', 'a', 'a', 'a']); 

// EXPECTED: True, False, False, True 
// ACTUAL: True, False, False, True 
testRegex(/a/, ['a', 'b', 'b', 'a']); 

Utworzyłem pracy przykład kodu powyżej: http://jsfiddle.net/FishBasketGordo/gBWsN/

jestem brakuje czegoś? Czy wyniki nie powinny być takie same dla danych tablic ciągów znaków, niezależnie od tego, czy wzór jest globalny czy nie? Uwaga, mam przede wszystkim pracuje w Chrome, ale już zaobserwować podobne nieprawidłowych wyników w Firefox 4 i IE 8.

Odpowiedz

15

Jeśli zmienisz pętli testowej, co następuje:

for (var ii = 0; ii < array.length; ii++) { 
    document.writeln(ii + ', '); 
    document.writeln(array[ii] + ', '); 
    document.writeln(pattern.test(array[ii]) + '<br />'); 
    pattern.lastIndex = 0; 
} 

Następnie kod będzie praca. Problem polega na tym, że flaga "g" powoduje zatrzymanie obiektu RegExp. Wartość "lastIndex" jest ustawiona na 1 po pierwszej iteracji tej pętli, z powodu "g". Jeśli nie ustawisz go ponownie, aby zresetować wyszukiwanie, zakłada się, że podczas drugiego połączenia pojawi się pytanie, czy kontynuować od przesunięcia 1.

Używanie flagi "g" w wyrażeniu regularnym poza kontekstem wywołania ".replace()" ma i tak dziwne implikacje semantyczne.

+0

Moim celem wychodząc rano było ostatecznie użyć RegExp w 'replace', dlatego byłem za pomocą opcji globalnych na początku, ale jak mój RegExp, utknąłem na etapie pośrednim . – FishBasketGordo

6

To nie jest błąd, ale funkcja. Uzyskane wyniki nie są "niepoprawne", tylko nieoczekiwane.

10.3.2. Właściwości instancji RegExp

Każdy obiekt RegExp ma pięć właściwości. Właściwość source jest ciągiem tylko do odczytu, który zawiera tekst wyrażenia regularnego. Właściwość globalna jest wartością boolowską tylko do odczytu, która określa, czy wyrażenie regularne ma flagę g. Właściwość ignoreCase jest wartością boolowską tylko do odczytu, która określa, czy wyrażenie regularne ma flagę i. Właściwość wielowierszowa jest wartością boolowską tylko do odczytu, która określa, czy wyrażenie regularne ma flagę m. Ostatnią właściwością jest lastIndex, liczba całkowita do odczytu i zapisu. W przypadku wzorców z flagą g ta właściwość przechowuje pozycję w ciągu znaków , od której rozpoczyna się następne wyszukiwanie. Jest używany przez metody exec() i test(), jak opisano w poprzedniej sekcji.

Source

Powiązane problemy