Разница между '.' '?' и '*' в регулярных выражениях?

21

Могу ли я получить пример того, как эти три элемента (они называются метасимволами?) Отличаются?

Я знаю, что это *означает все или ничего, но я не уверен, что это правильный способ думать об этом. С другой стороны .и ?похоже тоже самое. Они соответствуют одному персонажу, верно?

posixKing
источник

Ответы:

16

Взято прямо из Википедии :

? Знак вопроса указывает на ноль или одно вхождение предыдущего элемента. Например, colou? R соответствует как «цвет», так и «цвет».

*Звездочка обозначает ноль или более вхождений предыдущего элемента. Например, ab * c соответствует «ac», «abc», «abbc», «abbbc» и так далее.

Большая разница в том, что звездочка соответствует нулю или большему количеству вхождений, а вопросительный знак соответствует нулю или одному вхождению. Сравните эти два примера:

$ printf "colour\ncolor\ncolouur\n" | egrep 'colou?r'                          
colour
color
$ printf "colour\ncolor\ncolouur\n" | egrep 'colou*r'                          
colour
color
colouur

Поскольку в colouurписьме u (предыдущий элемент перед классификатором ?) встречалось более одного раза, оно не соответствует ?, но соответствует*

Подобный пример:

$ printf "error\neror\ner\n" | egrep 'er?or'                                   
eror
$ printf "error\neror\ner\n" | egrep 'er*or'                                   
error
eror

Из той же страницы википедии:

Соответствует любому отдельному символу (многие приложения исключают символы новой строки, и именно те символы, которые считаются символами новой строки, зависят от аромата, кодировки символов и платформы, но можно с уверенностью предположить, что символ перевода строки включен). В выражениях в скобках POSIX символ точки соответствует литеральной точке. Например, ac соответствует «abc» и т. Д., Но [ac] соответствует только «a», «.» Или «c».

В нашем примере

$ printf "colour\ncolor\ncolouur\n" | egrep 'colo.r'                           
colour
$ printf "colour\ncolor\ncolouur\n" | egrep 'colou.r'                          
colouur

Соответственно, последний читается как match any line that has "colou", plus any character, plus letter "r"

Вывод

Вы спросили: «Я знаю, что« * »означает все или ничего, но я не уверен, что это правильный способ думать об этом. С другой». & '?' кажись же. " Как видите, точка и звездочка не совсем совпадают. Точка работает с любым символом, который может занимать эту конкретную позицию, а знак вопроса - с предыдущим элементом.

Сергей Колодяжный
источник
32

Вы можете путать регулярные выражения с глобусами оболочки

В синтаксисе регулярного выражения .представляет любой отдельный символ (обычно исключая символ новой строки), в то время *как квантификатор означает ноль или более предшествующего атома регулярного выражения (символ или группа). ?является квантификатором, означающим ноль или один экземпляр предшествующего атома, или (в вариантах регулярного выражения, которые его поддерживают) модификатор, который устанавливает поведение квантификатора как не жадное.

В глобусах оболочки ?представляет один символ (например, регулярное выражение .), а *представляет последовательность из нуля или более символов (эквивалентную регулярному выражению .*).

Несколько ссылок, которые вы можете найти полезными: http://www.regular-expressions.info/quickstart.html и http://mywiki.wooledge.org/glob

steeldriver
источник
6

Примечание: Examples provided are in Python.хотя концепция остается прежней.

'.'является совпадающим символом, который соответствует любому символу, кроме символа новой строки (это также может быть переопределено re.DOTALLаргументом в Python). Следовательно, это также называется Wildcard .

'*'является квантификатором (определяет частоту появления элемента). Сокращено от {0,} .

Это означает «соответствовать нулю или более» - группа, которая предшествует звезде, может встречаться в тексте любое количество раз. Он может полностью отсутствовать или повторяться снова и снова.

'?'также квантификатор . Сокращено от {0,1} .

Это означает «Совпадение нуля или одной группы, предшествующей этому вопросительному знаку». Это также можно интерпретировать как необязательную часть, предшествующую знаку вопроса .

например:

pattern = re.compile(r'(\d{2}-)?\d{10}')
mobile1 = pattern.search('My number is 91-9999988888')
mobile1.group()
Output: '91-9999988888'

mobile2 = pattern.search('My number is 9999988888')
mobile2.group()
Output: '9999988888'

В приведенном выше примере '?' указывает, что две цифры, предшествующие ему, являются необязательными. Они могут не встречаться или встречаться не более одного раза.

Разница между '.' а также '?':

'.'соответствует / принимает / проверяет любой отдельный символ для места, которое он содержит в регулярном выражении.

например:

pattern = re.compile(r'.ot')
pattern.findall('dot will identify both hot and got.')
Output: ['dot', 'hot', 'got']

'?'соответствует / проверяет нулевое или единичное вхождение группы, предшествующей ему .

Проверьте пример номера мобильного телефона.

То же самое и с '*'. Он проверит ноль или более вхождений группы, предшествующей ему .

Комбинация:

'.*': Принимает столько последовательностей, сколько доступно. Жадный подход .

'.*?«Принимает первую согласованную последовательность и останавливается. Нежадный подход

Для получения дополнительной информации, прочитайте следующие два вопроса ...

Давал Симария
источник