2012-11-05 28 views
9

Javascript Regular Expression działa dobrze po raz pierwszy, ale nie po raz drugi, działa ponownie po raz trzeci, a nie za 4. i tak dalej :(Javascript Wyrażenie regularne działa dobrze po raz pierwszy, ale nie po raz drugi, działa ponownie po raz trzeci, a nie za czwartą itd. Tak więc

Scenariusz:

<script language="javascript" type="text/javascript"> 
    var reg = /[^\w]/gi; 
    function checkNonWordChars() { 
     var str = $("#TestTextbox").val(); 
     if (reg.test(str)) { 
      alert('!!! Non-Word Char Exists !!!'); 
     } 
     else { 
      alert('input accepted'); 
     } 
    }  
</script> 

HTML:

<input type="text" id="TestTextbox" /> 
<input type="button" value="Test" onclick="checkNonWordChars();" /> 

Gdybym kliknij przycisk raz, będzie ogień alert mówiąc, że „!!! nie Słowo Char Exist s !!! ", ale jeśli kliknę jeszcze raz, uruchomi się komunikat" przyjęto dane wejściowe ":(

+1

czy w tym polu tekstowym masz jakieś narzędzia do obsługi rozmycia/zmiany/skupienia? – jbabey

Odpowiedz

7

opcja 1

użyć konstruktora zamiast dosłownego określenia:

var reg = new RegExp('[^\w]','gi'); 

Więcej o różnicach między dwoma tutaj: https://developer.mozilla.org/en-US/docs/Core_JavaScript_1.5_Guide/Regular_Expressions?redirect=no

WARIANT 2

Mark koniec sznurka z $ znak:

var reg = /[^\w$]/gi; 

opcja 3

Jeśli wyrażenie regularne używa flagi "G", można użyć metoda exec wiele razy, aby znaleźć kolejne dopasowania w tym samym ciągu. Gdy to zrobisz, wyszukiwanie rozpocznie się od substring z str określonej przez wyrażenie regularne lastIndex Właściwość (test również przesuwa właściwość lastIndex).

Źródło: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp/exec

Dlatego w przypadku test będzie działać tylko 1 oraz 3, 5, ... czasu.

Tylko w Firefoksie 3 znajduje się flaga y, gdy określony exec zawsze zaczyna się od 0 Nie lastIndex ale to chyba nie jest przydatna w Twoim przypadku.

Możesz usunąć flagę g.

+1

OPCJA 1 działa dobrze, a nie OPCJA 2, w każdym razie dziękuję za twój wpis –

+0

Twoje wyrecytowanie w opcji 2 jest złe. Właśnie dodajesz znak "$" do klasy postaci, potrzebujesz 'var reg =/[^ \ w] $/gi;'. Ale w każdym razie, myślę, że nie byłoby to tym, czego chciał OP, który sprawdzałby tylko, czy ostatni znak w łańcuchu nie jest słowem. – stema

9

Podejrzewam, że ma to coś wspólnego z faktem, że używa się modyfikatora gmakes the engine remember its state.

Spróbuj usunąć modyfikator g, ale i tak go nie potrzebujesz. Silnik zawsze będzie próbował znaleźć dopasowanie w całym ciągu. Dlatego modyfikator g tak naprawdę nie robi nic w połączeniu z funkcją test, ale jest raczej używany do match. Nie musisz też modyfikatora i, ponieważ \w zawiera zarówno małe, jak i duże litery.

I ostatnia rzecz. Wyrażenia regularne zapewniają wygodną \W, która jest przeciwieństwem \w, a zatem jest równoważna [^\w].

+0

Tak, masz rację, nie potrzebuję "g" lub "i" w tym przypadku, ale była to tylko próbka, którą testowałem, ponieważ moje oryginalne wyrażenie nie działało. Mam wyrażenia regularne takie jak '/ [^ ad^0-3 \ $ \ -]/gi' i inne, które wymagają' g' i 'i' –

+0

@NileshThakkar Jeśli używasz ich z' test', dlaczego potrzebujesz 'g '? –

+1

Najpierw przeczytaj moją odpowiedź, a następnie użyj konstruktora zamiast literalnej notacji: 'var reg = new RegExp ('[^ \ w]', 'gi');' http://jsfiddle.net/Kmmuy/ – sainiuc

1

Wygląda na to, że obiekt RegExp nie jest tak bezpaństwowy, jak nam się wydaje. Quick Fix jest przeniesienie var reg = /[^\w]/gi; wewnątrz metody checkNonWordChars()

poważaniem,

+1

Tak, jest to szybkie rozwiązanie, ale zły pomysł, gdy używam tego samego wyrażenia wiele razy –

+0

Alternatywnie, jeśli wyrażenie jest używane w różnych miejscach skryptu, a Ty nie chcesz tworzyć 1001 wystąpień RegExp, 'reg.compile (reg)' może działać, chociaż 'kompilacja' jest uważana za przestarzałą –

0

Jeśli trzeba mieć, że regex globalny, a następnie zmienić go na adres:

var reg = /[^\w]/ 

będzie działać tak samo dobrze, ale nie być buggy! Będzie również szybszy, ponieważ musi tylko sprawdzić jedną instancję niegrzecznej postaci, a nie zależy Ci na przypadku postaci z nie-słownymi znakami.

Powiązane problemy