Используя https://regex101.com/, я построил регулярное выражение, которое возвращает первое вхождение IP-адреса в строку.
RegExp:
(?:\d{1,3}\.)+(?:\d{1,3})
RegExp, включая разделители:
/(?:\d{1,3}\.)+(?:\d{1,3})/
Со следующей тестовой строкой:
eu-west 140.243.64.99
Возвращает полное совпадение:
140.243.64.99
Независимо от того, что я пробую с якорями и т.д., следующий скрипт bash не будет работать с сгенерированным регулярным выражением.
temp="eu-west 140.243.64.99 "
regexp="(?:\d{1,3}\.)+(?:\d{1,3})"
if [[ $temp =~ $regexp ]]; then
echo "found a match"
else
echo "No IP address returned"
fi
bash
regular-expression
rjm61
источник
источник
=~
Оператор обсуждается здесь в руководстве , где это написано Баш использует «расширенные регулярные выражения». Расширенные регулярные выражения описаны наregex(7)
странице руководства и кратко изложены здесь .Ответы:
\d
это нестандартный способ сказать «любая цифра». Я думаю, что это происходит от Perl, и многие другие языки и утилиты также поддерживают Perl-совместимые RE (PCRE). (и, например, GNU grep 2.27 в Debian stretch поддерживает подобное\w
для символов слова даже в обычном режиме.)Bash не поддерживает
\d
, так что вам нужно явно использовать[0-9]
или[[:digit:]]
. То же самое для группы без захвата(?:..)
, используйте только(..)
вместо этого.Это должно напечатать
match
:источник
grep
поддерживает\d
без-P
?\w
и\b
, что я узнал от Perl, поэтому я запутался.\d
или PCRE являются «нестандартными». Они довольно стандартны, просто отличаются от оригинальных регулярных выражений и расширенных регулярных выражений.\d
. Хотя вы правы в том, что PCRE довольно стандартны или наименее четко определены. Раздражает проблема в том , что GNU Grep (или Glibc) поддерживает некоторые PCRE-атомов, по крайней мере ,\w
и\s
при интерпретации ERE, и в этом контексте они очень являются нестандартными. Моя формулировка вполне может быть отчасти из-за этого и из-за неправильного выбора, который\d
был аналогично поддержан GNU.(:...)
и\d
являются операторами регулярного выражения perl или PCRE (как в GNUgrep -P
).bash
поддерживает только расширенные регулярные выражения, как, заgrep -E
исключением того, что для регулярных выражений , переданных буквально, в[[ text =~ regexp-here ]]
отличие от результата раскрытия без кавычек (как в[[ text =~ $var ]]
или[[ test =~ $(printf '%s\n' 'regexp-here') ]]
), он ограничен расширенным набором функций регулярного выражения POSIX.Таким образом, даже в системах, где
grep -E '\d'
это сработает (GNU ERE уже импортировали некоторые расширения из регулярных выражений perl, как, например, в\s
будущих версиях\d
), вам придется использовать:в
bash
для его работы ([[ $text =~ \d ]]
не будет).Для оболочки, которая поддерживает PCRE, вы можете использовать
zsh
вместо этого:ksh93 также поддерживает собственную реализацию perl-подобных регулярных выражений (не полностью совместимых) как часть сопоставления с образцом. Там вы бы использовали:
(обратите внимание на
=
вместо=~
. Вы можете использовать временные переменные, поскольку он очень глючит, когда вы этого не делаете)источник
На сайте regex101.com по умолчанию используется PCRE (смотрите в верхнем левом углу), и на нем отсутствует поддержка расширенного синтаксиса регулярных выражений. Это "Perl-совместимые регулярные выражения", которые происходят (как и следовало ожидать) от Perl.
PCRE поддерживается некоторыми инструментами (например
grep -P
) в некоторых условиях, но поддержка bash regex внутри[[…]]
идиомы предназначена только для расширенного регулярного выражения (напримерgrep -E
).В расширенном регулярном выражении неперехватывающая
(?…)
скобка не существует, и \ d также отсутствует. Вам нужно использовать простые(…)
и[0-9]
:источник