Регулярное выражение в JavaScript не такое же, как в PHP

У меня есть регулярное выражение для соответствия именам пользователей (которые работают на 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]* , что преуспевает.