2012-03-26 3 views
4

я имел another question и хотя это был дан ответ я не понимаю, почему регулярное выражение влияет так, как этоПочему флагом Regex Javascript // g влияет на состояние?

От w3schools он говорит

г: Выполнение глобального матча (найти все матчи, а не останавливаясь после в первом матче)

Хорошо, конечно. Я понимаю. Вот почему я получаю массив в этом коде

var str="The rain in SPAIN stays mainly in the plain"; 
var patt1=/ain/gi; 
document.write(str.match(patt1)); 

Выход:

ain,AIN,ain,ain 

Regex схожа с /g он заменит более одного экземпляра.

Однако в матче

var re=/hi/gi; 
alert(re.test("hi") + " " + re.test("hi")); 

Результат "истинно ложь".

Теперь почему $%^& делает это? Строка в обоих тестах одинакова! Раньше я думал, что глобальный означает, что он будет искать новые строки (именно это я и хотел сделать в этом тесте). Самое первое, что я процитировал, было о том, что g является глобальным матчем.

Ничего не упоминает об этом, затрагивая СЛЕДУЮЩИЙ ВЫЗОВ! без/g код будет работать правильно (также мне не нужно переходить на новые строки). ПОЧЕМУ это влияет на следующий тест? gumbo ответ упоминает, что он влияет на lastIndex через вызовы и что%^& * я понятия не имел, что есть общее состояние, поскольку другие две функции не использовали его, пока я использовал флаг g. Я хотел только true и false, но если что-либо не должно соответствовать возврату int, содержащему количество совпадений, найденных в глобальном масштабе? (т.е. 1 в «привет», но 2 в строке «hihi»).

Почему heck g влияет на мой следующий вызов при выполнении regex.test ?! Кроме того, если вы можете, укажите, когда я действительно хочу, чтобы эта функция была включена.

+0

w3schools не заслуживает доверия, см. [W3fools] (http://w3fools.com) для деталей. Если вы получаете информацию о JS в любом месте, получите ее из [MDN] (https://developer.mozilla.org/). – zzzzBov

+0

@zzzzBov Я пытался найти руководство для javascript в прошлом и не думал о mdn bc, я думал, что это был firefox. хорошо, я проверю там в следующий раз! –

+0

@ acidzombie24, для окончательного подтверждения, используйте спецификацию ECMAscript, загружаемую в формате PDF. Да, это громоздко использовать в качестве быстрой справки, но это авторитетное руководство! MDN, вероятно, является вашим первым портом по вызову, как говорит zzzzBov. – Doin

ответ

9

Когда вы используете глобальный флаг в регулярном выражении, свойство lastIndex обновляется. Свойство lastIndex является индексом начала следующего совпадения.

https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/RegExp

Вы можете сбросить последний индекс перед вызовом снова. См

Why RegExp with global flag in Javascript give wrong results?

+0

ok, но он не упоминает об этом глобальном, хотя в нем упоминается lastIndex (без особого объяснения) и exec. Нет никакой очевидной причины, почему у этого есть это поведение или для чего я могу его использовать. -edit- Он даже не упоминает как lastIndex, так и глобальные. Подобное поведение совершенно недокументировано! –

+0

Если вы прочтете комментарии по связанному SO-вопросу - «Это то, что специфицирует спецификация. Итак, это выбор дизайна. Это все в разделе 15.10.6.2 спецификации ECMAScript 3». –

+0

Он не говорит о соображениях дизайна. Я предполагаю, что если ваш исполняющий exec (который я никогда не использовал на данный момент), это имеет смысл. Но я использую тест здесь. Я ... не ожидаю такого поведения, особенно когда матч и замена, похоже, не имеют этого. +1 bc вы ответили на вопрос, хотя я думаю, что я считаю, что спецификации ECMAScript3 носят абсурд. –

0

Для меня главная проблема, кажется, что вы используете «г» модификатор вместо «т» модификатором, который в основном добавляет «\ п» для набора соответствующих символов по ''.

Модификатор 'g' используется, если вы хотите итерации по заданным совпадениям, пожалуйста, посмотрите на http://perldoc.perl.org/perlretut.html#Using-regular-expressions-in-Perl (и выполните поиск на этой странице для «Глобального соответствия»). Хотя это документация Perl, есть хороший пример для использования.

Реализация Javascript еще испорчено, насколько я могу видеть, потому что также

alert(re.test(new String("hi")) + " " + re.test(new String("xhi"))); 

дает результаты, которые вы описали. Но теперь две строки являются разными Объектами, и они имеют разные значения, которые должны были бы сбросить индекс re, но, очевидно, этого не произошло.

Смежные вопросы