У меня есть регулярное выражение для соответствия именам пользователей (которые работают на PHP с помощью preg_match
):
/[az]+(?(?=\-)[az]+|)\.[1-9][0-9]*/
Этот шаблон соответствует именам пользователей формы abc.124
, abc-abc.123
и т. Д.
Однако, когда я беру это на JavaScript:
var re = new RegExp("/[az]+(?(?=\-)[az]+|)\.[1-9][0-9]*/");
Я получаю синтаксическую ошибку:
SyntaxError: Invalid regular expression: /[az]+(?(?=-)[az]+|).[1-9][0-9]*/: Invalid group
(?(?=\-)[az]+|)
состоит в том, чтобы сказать, что после [az]+
мы видим a -
тогда утверждаем, что [az]+
находится в противном случае, ничего не соответствует. Все это отлично работает в PHP, но чего мне не хватает в JavaScript, который отличается?
EDIT: Я ценю комментарии, и теперь у меня есть последний вопрос относительно этого:
var str="accouts pending removal shen.1206"; var patt= new RegExp("/[az]+(?:-[az]+)?\.[1-9][0-9]*/"); var result=patt.exec(str); alert(result);
Это предупреждение появляется как null
? Но если я сделаю следующее, это будет работать:
var patt=/[az]+(?:-[az]+)?\.[1-9][0-9]*/; var result=patt.exec(str); alert(result);
Почему «новый RegExp ()» не работает?
Различные механизмы регулярных выражений поддерживают различные функции. Условные выражения не поддерживаются Javascript.
В любом случае условное значение не является необходимым для вашего шаблона. Я бы упростил ваше выражение в /[az]+(?:-[az]+)?\.[1-9][0-9]*/
, что легче понять и будет работать как в PCRE PHP, так и в Javascript.
JavaScript не использует ту же реализацию регулярного выражения, что и PHP. В этом случае JavaScript не поддерживает условное выражение (?(?=regex)then|else)
(см. Сравнение ароматов регулярного выражения ). Но вы можете использовать следующее регулярное выражение, которое эквивалентно вашему:
/[az]+(?:-[az]+)?\.[1-9][0-9]*/
И при использовании конструктора RegExp
для создания регулярного выражения (вместо синтаксиса литералов регулярного выражения /…/
) вам также нужно избежать экранирования \
. Так:
var re = /[az]+(?:-[az]+)?\.[1-9][0-9]*/; // OR var re = new RegExp("/[az]+(?:-[az]+)?\\.[1-9][0-9]*/");
Ваше условие не работает даже в PHP. Lookahead – (?=-)
– преуспевает, если следующий символ является дефисом, но он не использует дефис. Затем [az]+
пытается совпадение в той же позиции и сбой, потому что следующий символ все еще -
. Вам придется снова сопоставить дефис – -[az]+
– но, как говорили другие, вы все равно не должны использовать условное выражение.
Условные соблазнительны; они кажутся, что они должны быть очень полезными, но на практике они редко бывают. Они заманивают нас, отражая то, как мы, естественно, думаем о некоторых проблемах: «Я хочу сопоставить некоторые буквы, и если персонаж, следующий за ними, является дефисом, я хочу сопоставить его и еще несколько писем».
Вы сэкономите много хлопот, если научитесь думать немного больше как регулярное выражение: «Я хочу совместить кусок букв, необязательно сопровождаемый дефисом и еще несколькими буквами». Реджикс практически пишет:
/[az]+(?:-[az]+)?/
(The \.[1-9][0-9]*
часть вашего регулярного выражения была прекрасной, я оставил ее, чтобы я мог сосредоточиться на условном аспекте.)
EDIT: Чтобы ответить на вопрос в комментарии, да, ваше регулярное выражение соответствует строкам обеих форм: abc.124
и abc-abc.123
. Но посмотрите, какая часть строки соответствует:
Array ( [0] => Array ( [0] => abc.124 [1] => abc.123 ) )
Случается, что первый [az]+
сначала соответствует первому abc
в abc-abc.123
. Тогда lookahead соответствует -
без его потребления, а второй [az]+
пытается сопоставить дефис и терпеть неудачу, как я сказал ранее.
Не сумев найти совпадение в этой позиции, двигатель регулярного выражения начинает натыкаться вперед на один символ за раз и повторять попытку. Когда он добирается до второго abc
, первый [az]+
соответствует ему и отсылается к следующей части регулярного выражения – условному.
Следующий символ во входной строке .
, поэтому просмотр не получается. Условное условие не обязано соответствовать чему-либо, потому что вы не предоставили подшаблон для предложения else
. Таким образом, условие ничего не соответствует, и управление переходит к следующей части регулярного выражения \.[1-9][0-9]*
, что преуспевает.