Как стать автором
Обновить

Комментарии 54

Я обычно смотрю стандарт, но за ссылку спасибо.
Автор не раскрыл темы с позицией поиска.
На самом деле, вполне возможно работать не пересоздавая объект регулярного выражения.

Достаточно перед очередным поискoм lastIndex присвоить нулю, и всё будет работать как ожидается.
А зачем понадобилось вписвать сюда параметр /g?
Разве не логичнее было его не писать вообще?
Если продолжить эту мысль, то вместо
/([0-9])+/g
можно записать сперва
/([0-9])+/
а затем
/([0-9])/
и наконец
/[0-9]/
Также скобки в начальном выражении совершенно не нужны, первое упрощение могло выглядеть как /[0-9]+/.
/\d+/ ;)
Там и "+" не нужен. В условии ведь было «хотя бы одна цифра». Значит, после нахождения первой цифры можно остановиться и вернуть true.
А если ещё убрать объявление регулярки перед функцией:

function has_digit(s) { return /\d/.test(s); }


то автор вообще не столкнулся бы с проблемой :)
автор хотел показать пример с кэшированием регулярки, чтобы при каждом вызове не происходил повторный парсинг и создание объекта RegExp
Вот до чего доводят преждевременные «оптимизации»
Очевидная вещь же. Если вы этого не знали, значит это лишь ваша оплошность и нехватка опыта. Таких вещей бесчисленное множество, зачем о каждой писать на Хабре? =)
Может оказатсья так, что он будет не единственным с данной проблемой. В этом то и смысл — набраться опыта на чужих ошибках :)
Я бы не сказал, что подобных несоответствий так много.

И потом не так уже часто в этом блоге статьи пишутся, разве нет?

А теперь запускаем код в FF 3.6 или любом достаточно старом браузере и любуемся на результаты.
javascript: function test(d){return /([0-9])+/g.test(d)}; alert( [test('5'), test('5')] )


Автор так бежал, так спешил поделиться своей находкой, что до самой сути и не дошел. А если бы умел пользоваться поиском, нашел бы замечательную статью на javascript.ru.
Статью дальше ката вообще читали? Или так спешили поделиться своей находкой, что не хватило времени?
Нет, что Вы! Мне
/([0-9])+/g.test("abc")

Этот код не вызывает проблем.
с неба свалилось.
Зря умничаете. Отличие вашего кода и того кода, что привёл автор в том, что у вас при каждом тесте создаётся новое регулярное выражение, а у автора — используется одно и то же. Попробуйте что-то типа такого:
javascript: function test(d){return test.regexp.test(d)}; test.regexp =  /([0-9])+/g; alert( [test('5'), test('5')] )
Эх, TheShock, а я считал Вас разбирающимся в JS…
Почитали бы хотя бы статью по ссылке
То есть, простыми словами, литеральный регэксп не создается каждый раз при вызове var r = /regexp/.
Вместо этого браузер возвращает уже существующий объект, со всеми свойствами, оставшимися от предыдущего запуска.
Это баг спецификации ES3, и в ES5 он уже исправлен (соответственно, и некоторые браузеры подтянулись).
Я говорю не про теоретические изыскания, а про то, как есть на практике.
Как бы там ни было, даже в Хроме восьмом этот «баг спецификации» проявляется. Хотя, с тем, что это баг, я согласен.
Firefox 3.6.16 true, false.
Что я делаю не так?

Комментатор так бежал, так спешил поделиться своей находкой, что даже запустить свой код не удосужился?
*facepalm*
Вы на код посмотрели перед запуском? Автор утверждает, что код
> /([0-9])+/g.test(«abc»)
Не вызывает проблем. Внимание, вопрос: чем таким '5' во втором вызове отличается от '5' в первом, что второй вызов вернет отличный от первого результат?
А, прошу прощения, я не так вас понял. Действительно, в старых и новых браузерах этот код работает иначе.
Довольно интересно. Google Chrome (10.0.648.6 dev): true, true
Это неправильный код. Смотрите моё объяснение выше.
Эта статья демонстрирует полное незнание регулярных выражений. Зачем этой проверке флаг g? Зачем скобки вокруг символьного класса?
Скобки не нужны. Регулярку можно упростить еще сильней. Суть не в этом, а в том, что Вы можете это выражение взять из другой части кода. Где оно реально что-то выделяло. И забыть убрать флаг global.
И получить эту трудноотлавливаемую проблему.
Копипаст — одно из самых больших зол в программировании.
Третье после отсутствия мозгов и второе после отсутствия практики.
Отсутствие практики — не грех.
Угу. Это только зло.

А вот нежелание учиться — грех.
Забавный факт. Не обращал на него внимания.
На ActionScript, который основан на том же стандарте, что и JavaScript, данное поведение повторяется.
Это не поведение, это продолжение поиска
Сколько пафоса в статье, а толком объяснить так и не смог. Столько всякой воды вокруг одной строки с ответом, что хрен найдешь ее там.
эээ, я вот одного не пойму — сделав банальную ошибку с инициализацией, зачем обвинять в этом хорошие ресурсы и документацию?
Спасибо за эту статью, но если внимательно читать книги, вот например у Флэнегана написано «Когда exec() вызывается для регулярного выражения, содержащего флаг g, метод устанавливает свойство lastIndex объекта регулярного выражения равным номеру позиции символа, следующего непосредственно за найденной подстрокой. Когда метод exec() вызывается для того же регулярного выражения второй раз, он начинает поиск с символа, позиция которого указана в свойстве lastIndex.»

Читайте книги внимательно, и не будет таких вот трудновылавливаемых ошибок
Ресурсы все правильно пишут, единственно что про lastIndex умалчивают. Кстати, автор javascript.ru абсолютно в курсе этого поведения, в частности на мастер-классах про это рассказывает.
Вы такими темпами JavaScript изучите :)
Да, интересное исследование, сам натыкался на такой «финт», просто не думал, что можно из этого написать заметку на Хабре :)
>Удивляет, что большинство сетевых ресурсов по JavaScript оказались бесполезны.

2006 год — обсуждалось на Винграде
2007 год — обсуждалось на ДКлабе

Обсуждалось и задолго раньше, ссылок из глубокого прошлого под рукой нет, поверьте на слово. И конечно же это поведение описано и на более молодых ресурсах, и в ньюсах англоязычных, и в книгах (того же Флэнагана), и в спеках языка, и в самой экме… Но вдумчиво не читали, не читаем и не будем читать. Всё как всегда — ни дня без чудесного открытия… ;-)
… мы хотим проверить регулярным выражением, что в строке есть хотя бы одна цифра ...

/\d/.test(str);

Ну вот так как-то.
а я вот так делаю:

function has_digit(s) { return (s.search(digits) != -1) }
bool b;

if (Convert.ToString(b).Length == 4) //True
{

}
else
?
Хотите казаться умным? Молчите.
парсер — лох. я хотел написать код от коллег-индусов.
не надо делать поспешных выводов насчёт ума
Парсер не лох, юзайте кнопочку «предпросмотр». А раз Вы ответили «кодом от коллег-индусов», то похоже вы сравнивали его с кодом человека выше. Код человека выше нормален.
Очередной пост на главной про изучение студентом регулярных выражений
Блин… прочитал почти все комментарии и вообще запутался что верно, а что нет
Какие регулярки? Автор, учи русский.
«Вам очевидно — почему?» :)
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации