Регулярное выражение: {n} и {n, m} игнорируют максимальное количество повторений - PullRequest
0 голосов
/ 23 мая 2018

У меня есть вопрос о максимальном количестве повторений регулярных выражений: {n} и {n, m}.

$ man grep
...
Repetition
    A regular expression may be followed by one of several repetition operators:
...
    {n}    The preceding item is matched exactly n times.
    {n,}   The preceding item is matched n or more times.
    {,m}   The preceding item is matched at most m times.  This is a GNU extension.
    {n,m}  The preceding item is matched at least n times, but not more than m times.
...

Теперь рассмотрим тестовый файл:

$ cat ./sample.txt
1
12
123
1234

Затем grepэто для [0-9] (цифр), которое повторяется ровно 2 раза:

$ grep "[0-9]\{2\}" ./sample.txt
12
123
1234

?Почему это включает 123 и 1234?

Кроме того, я grep один и тот же текстовый файл для цифр, повторяющихся не менее 2 раз, но не более 3 раз:

$ grep "[0-9]\{2,3\}" ./sample.txt
12
123
1234

???Почему это возвращает «1234»?

Очевидный обходной путь - использовать grep и reverse-grep для фильтрации чрезмерных результатов.Например,

$ grep "[0-9]\{2,\}" ./sample.txt | grep -v "[0-9]\{4,\}"
12
123

Может кто-нибудь помочь мне понять, почему {n} возвращает строку, содержащую шаблон, повторяющийся более n раз?И почему {n, m} возвращает шаблон, повторяющийся более m раз ??

Ответы [ 2 ]

0 голосов
/ 23 мая 2018

Шаблон может быть найден в более длинном тексте или может следовать точно такой же схеме.Для grep используйте параметр -o, чтобы увидеть, где регулярное выражение нашло совпадение.Две цифры можно найти в числе, состоящем из двух цифр, или в номере длиной 10 цифр.

Другой ответ указывает на две привязки, но есть маркер границы слова \b, который соответствует позиции границыесли используется.Это закрывает оба конца.К сожалению, POSIX BRE (стандартное выражение grep по умолчанию) не поддерживает это, но в GNU sed вы можете включить регулярные выражения Perl и протестировать его:

grep -P '\b[0-9]{2}\b' file

только с grep, двумя \< и \>соответствует той же позиции:

grep '\<[0-9]\{2\}\>' file
0 голосов
/ 23 мая 2018

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

$ grep "[0-9]\{2\}" ./sample.txt будет соответствовать любой строке, содержащей 2 цифры.

Используйте ^ для принудительного выраженияначинать с начала строки и $, чтобы заставить ее совпадать с концом строки.например.

$ grep '^[0-9]\{2\}$' ./sample.txt
# Using single quotes to avoid potential substitution issues. Hat tip to @ghoti

Это должно вернуть только 12.

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