В чем разница между квадратными скобками и круглыми скобками в регулярном выражении?
Вот регулярное выражение, которое я создал для использования в JavaScript:
var reg_num = /^(7|8|9)\d{9}$/
Вот еще один, предложенный членом моей команды.
var reg_num = /^[7|8|9][\d]{9}$/
Правило должно подтверждать номер телефона:
- Должно быть только десять цифр.
- Первый номер должен быть любым из 7, 8 или 9.
3 ответа
Эти регулярные выражения эквивалентны (для сопоставления):
/^(7|8|9)\d{9}$/
/^[789]\d{9}$/
/^[7-9]\d{9}$/
Объяснение:
(a|b|c)
является регулярным выражением "ИЛИ" и означает "a или b или c", хотя наличие скобок, необходимых для ИЛИ, также фиксирует цифру. Чтобы быть строго эквивалентным, вы должны написать(?:7|8|9)
сделать его не захватывающей группой.[abc]
является "классом символов", что означает "любой символ из a, b или c" (класс символов может использовать диапазоны, например[a-d]
знак равно[abcd]
)
Причина, по которой эти регулярные выражения похожи, состоит в том, что класс символов является сокращением для "или" (но только для одиночных символов). В чередовании вы также можете сделать что-то вроде (abc|def)
который не переводится в класс персонажа.
Совет вашей команды почти верен, за исключением ошибки, которую он совершил. Как только вы узнаете почему, вы никогда не забудете это. Посмотрите на эту ошибку.
/^(7|8|9)\d{9}$/
Что это делает:
^
а также$
обозначает привязанные соответствия, которые утверждают, что подшаблон между этими привязками является полным соответствием. Строка будет соответствовать только в том случае, если подшаблон соответствует всему, а не только разделу.()
обозначает группу захвата.7|8|9
обозначает совпадение любого из7
,8
, или же9
, Это делается с чередованием, что оператор труб|
делает - чередуя чередования. Это возвращает назад между чередованиями: если первое чередование не сопоставлено, двигатель должен вернуться до того, как указатель переместился во время совпадения чередования, чтобы продолжить сопоставление следующего чередования; Принимая во внимание, что класс персонажа может продвигаться последовательно. Посмотрите это совпадение на движке регулярных выражений с отключенной оптимизацией:
Pattern: (r|f)at
Match string: carat
Pattern: [rf]at
Match string: carat
\d{9}
соответствует девяти цифрам.\d
является сокращенным метасимволом, который соответствует любым цифрам.
/^[7|8|9][\d]{9}$/
Посмотрите, что он делает:
^
а также$
обозначает также привязанные спички.[7|8|9]
это класс персонажа. Любые персонажи из списка7
,|
,8
,|
, или же9
могут быть сопоставлены, таким образом,|
был добавлен неправильно. Это соответствует без возврата.[\d]
класс персонажа, который обитает в метасимволе\d
, Кстати, сочетание использования символьного класса и одного метасимвола является плохой идеей, поскольку уровень абстракции может замедлить сопоставление, но это только деталь реализации и применяется только к нескольким реализациям регулярных выражений. JavaScript не один, но он делает подшаблон немного длиннее.{9}
указывает, что предыдущая одиночная конструкция повторяется в общей сложности девять раз.
Оптимальное регулярное выражение /^[789]\d{9}$/
, так как /^(7|8|9)\d{9}$/
захватывает излишне, что налагает снижение производительности на большинство реализаций регулярных выражений ( javascript является одним из них, учитывая, что вопрос использует ключевое слово var
в коде это, вероятно, JavaScript). Использование php, который запускается на PCRE для сопоставления preg, оптимизирует отсутствие обратного отслеживания, однако мы также не находимся в PHP, поэтому используем классы []
вместо чередований |
дает выигрыш в производительности, так как совпадение не возвращается, и поэтому совпадает и терпит неудачу быстрее, чем при использовании вашего предыдущего регулярного выражения.
Первые 2 примера действуют совсем по-другому, если вы заменяете их чем-то. Если вы соответствуете по этому:
str = str.replace(/^(7|8|9)/ig,'');
вы бы заменили 7, 8 или 9 пустой строкой.
Если вы соответствуете по этому
str = str.replace(/^[7|8|9]/ig,'');
ты заменишь 7
или же 8
или же 9
ИЛИ ВЕРТИКАЛЬНЫЙ БАР!!!! по пустой строке.
Я только что выяснил это трудным путем.