Нужна помощь в понимании того, почему эта строка в grep тянет IP-адреса, а не эту другую строку - PullRequest
0 голосов
/ 09 февраля 2019

Следующее утверждение взято из домашнего задания, которое я проверил и ответил на него, но я просто не понимаю, почему эта строка ведет себя так, как она, и я хочу понять, почему.Я понимаю, почему это выражение некорректно при поиске IP-адреса, но я не до конца понимаю, почему оно ведет себя так, как оно происходит, поскольку кажется, что вопросительный знак на самом деле не ведет себя так 0 или 1 раз, как предполагалось.

"user @ machine: ~ $ grep -E '[01]? [0-9] [0-9]?'"

Насколько я понимаю" [01]? "следует искать любое число 0-1, как указано в скобках, в то время как знак вопроса говорит grep искать только ноль или только один экземпляр и аналогично «[0-9]?».Дело в том, что эта строка будет печатать неограниченное количество цифр, намного превышающих 3 цифрыЯ исключил, что это было связано с тем, что в 3-й скобке отсутствовал вопросительный знак, поскольку он по-прежнему печатал бы неограниченное количество цифр, если бы я передавал эхо-сигнал или использовал тестовый файл .txt, полный цифр.

Этот пример заставил меня задуматься, как правильно найти IP с помощью grep.Поэтому я нашел бесчисленное множество примеров, таких как следующее выражение для октетов IPv4:

\. (25 [0-5] \ | 2 [0-4] [0-9] \ | [01] [0-9]] [0-9] \ | [0-9] [0-9]). \

Это говорит мне, чтобы я искал любое число 2-5 в любом месте 0-5 раз?0-5 слишком много цифр для октета.Это говорит мне, чтобы искать любое число от 0-5 до 25 раз?Опять же, это слишком много цифр для октета.Что означает \ 2 [0-4] [0-9] \ в этом случае?Я запутался в том, как это выражение находит числа строго между 1-255?

1 Ответ

0 голосов
/ 09 февраля 2019

Посмотрите на это следующим образом: x?[0-9]x? соответствует всему, что содержит цифру, потому что оба x: es являются необязательными.Вы могли бы также пропустить их, потому что они вообще не ограничивают совпадение.

25[0-5] ищет 25, за которым следует цифра в диапазоне 0-5.Другими словами, выражение соответствует номеру в диапазоне 250-255.

Полное выражение в вашем примере ищет число в диапазоне 00-255, перечисляя строки, начинающиеся с 25, 20-24 и т. Д.;хотя он неполный, поскольку не допускает однозначных чисел.

Выражение соответствует одному октету (не полностью), а не целому IP-адресу.Вот обычный способ сопоставления адреса IPv4:

([3-9][0-9]?|2([0-4][0-9]?|5[0-9]?|[6-9])?|1([0-9][0-9]?)?)(\.([3-9][0-9]?|2([0-4][0-9]?|5[0-9]?|[6-9])?|1([0-9][0-9]?)?){3}

, где квадратные скобки выражают классы символов, которые соответствуют одному символу из набора, а заключительные фигурные скобки {3} выражают повторение.

Некоторые диалекты регулярных выражений (например, POSIX grep) требуют обратной косой черты перед | и \(, но я использовал расширенную нотацию (как у grep -E и большинство онлайн-инструментов исследования регулярных выражений), которая не требуетобратная косая черта.

...