Регулярные выражения в JavaScript не такие, как в PHP - PullRequest
2 голосов
/ 23 августа 2010

У меня есть регулярное выражение для сопоставления имен пользователей (которые работают в PHP, используя preg_match):

/[a-z]+(?(?=\-)[a-z]+|)\.[1-9][0-9]*/

Этот шаблон соответствует именам пользователей в форме abc.124, abc-abc.123 и т. Д.

Однако, когда я беру это в JavaScript:

var re = new RegExp("/[a-z]+(?(?=\-)[a-z]+|)\.[1-9][0-9]*/"); 

Я получаю синтаксическую ошибку:

SyntaxError: Invalid regular expression: /[a-z]+(?(?=-)[a-z]+|).[1-9][0-9]*/: Invalid group

(?(?=\-)[a-z]+|) означает, что если после [a-z]+ мы видим -, тогда утверждаем, что [a-z]+ следует за ним, иначе ничего не соответствует. Все это прекрасно работает в PHP, но чего мне не хватает в JavaScript, который отличается?

РЕДАКТИРОВАТЬ: Я ценю комментарии, и теперь у меня есть последний вопрос по этому поводу:

    var str="accouts pending removal shen.1206";
    var patt= new RegExp("/[a-z]+(?:-[a-z]+)?\.[1-9][0-9]*/"); 
    var result=patt.exec(str);
    alert(result); 

Это предупреждение появляется как null? Но если я сделаю следующее, это сработает:

var patt=/[a-z]+(?:-[a-z]+)?\.[1-9][0-9]*/;
var result=patt.exec(str);
alert(result); 

Почему «new RegExp ()» не работает?

Ответы [ 3 ]

5 голосов
/ 23 августа 2010

Различные движки регулярных выражений поддерживают разные функции. Условия не поддерживаются Javascript.

В любом случае, условное обозначение не требуется для вашего шаблона. Я бы упростил ваше выражение до /[a-z]+(?:-[a-z]+)?\.[1-9][0-9]*/, что проще для понимания и будет работать как в PHP PCRE , так и в Javascript.

3 голосов
/ 23 августа 2010

JavaScript не использует ту же реализацию регулярных выражений, что и PHP. В этом случае JavaScript не поддерживает условное выражение (?(?=regex)then|else) (см. сравнение разновидностей регулярных выражений ). Но вы можете использовать следующее регулярное выражение, эквивалентное вашему:

/[a-z]+(?:-[a-z]+)?\.[1-9][0-9]*/

И при использовании конструктора RegExp для создания регулярного выражения (вместо буквального синтаксиса регулярного выражения /…/) вам также необходимо экранировать экранирование \. Итак:

var re = /[a-z]+(?:-[a-z]+)?\.[1-9][0-9]*/;                 // OR
var re = new RegExp("/[a-z]+(?:-[a-z]+)?\\.[1-9][0-9]*/");
2 голосов
/ 24 августа 2010

Ваше условное выражение не работает даже в PHP.Взгляд вперед - (?=-) - успешен, если следующий символ - дефис, но он не потребляет дефис.Затем [a-z]+ пытается найти совпадение в той же позиции и терпит неудачу, потому что следующий символ по-прежнему -.Вам нужно будет снова сопоставить дефис - -[a-z]+ - но, как сказали другие, вам все равно не следует использовать условные выражения.

Условные выражения соблазнительны;они кажутся как будто они должны быть очень полезными, но на практике они редко бывают полезными.Они заманивают нас, отражая то, как мы естественным образом думаем об определенных проблемах: «Я хочу сопоставить несколько букв, а если следующий за ними символ - дефис, я хочу сопоставить его и еще несколько букв».

Вы избавите себя от многих хлопот, если научитесь думать немного больше как регулярное выражение: «Я хочу сопоставить кусок букв, за которыми, возможно, следуют дефис и еще несколько букв».Регулярное выражение практически записывается само по себе:

/[a-z]+(?:-[a-z]+)?/

(\.[1-9][0-9]* часть вашего регулярного выражения была в порядке; я оставил это, чтобы сосредоточиться на условном аспекте.)


РЕДАКТИРОВАТЬ: Чтобы ответить на вопрос в комментарии, да, ваше регулярное выражение совпадает со строками обеих форм: abc.124 и abc-abc.123.Но посмотрите, какая именно часть строки соответствует:

Array
(
    [0] => Array
        (
            [0] => abc.124
            [1] => abc.123
        )

)

В результате получается, что первое [a-z]+ изначально совпадает с первым abc в abc-abc.123.Затем предвидение сопоставляет -, не потребляя его, а вторая [a-z]+ пытается сопоставить дефис и терпит неудачу, как я говорил ранее.

Не найдя совпадения в этой позиции, запускается механизм регулярных выраженийнатыкаясь вперед по одному персонажу за раз и пытаясь снова.Когда он достигает второго abc, первый [a-z]+ соответствует ему и передает следующую часть регулярного выражения - условное.

Следующим символом во входной строке является ., поэтому просмотр не выполняется.Условие не должно совпадать ни с чем, потому что вы не указали подшаблон для предложения else.Таким образом, условное соответствие ничему не соответствует, и управление переходит к следующей части регулярного выражения, \.[1-9][0-9]*, которая завершается успешно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...