Bash =~ regex 和 https://regex101.com/

rjm*_*m61 20 bash regular-expression

使用https://regex101.com/我构建了一个正则表达式来返回字符串中第一次出现的 IP 地址。

正则表达式:

(?:\d{1,3}\.)+(?:\d{1,3})
Run Code Online (Sandbox Code Playgroud)

RegExp 包括分隔符:

/(?:\d{1,3}\.)+(?:\d{1,3})/
Run Code Online (Sandbox Code Playgroud)

使用以下测试字符串:

eu-west                       140.243.64.99 
Run Code Online (Sandbox Code Playgroud)

它返回一个完整的匹配:

140.243.64.99
Run Code Online (Sandbox Code Playgroud)

无论我尝试使用锚点等做什么,以下 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
Run Code Online (Sandbox Code Playgroud)

ilk*_*chu 27

\d是说“任何数字”的非标准方式。我认为它来自 Perl,而且许多其他语言和实用程序也支持与 Perl 兼容的 RE (PCRE)。(例如,Debian 中的 GNU grep 2.27\w甚至在正常模式下也支持类似的单词字符。)

\d但是,Bash 不支持,因此您需要明确使用[0-9][[:digit:]]。非捕获组相同,请改为(?:..)使用(..)

这应该打印match

temp="eu-west                       140.243.64.99            "
regexp="([0-9]{1,3}\.)+([0-9]{1,3})"
[[ $temp =~ $regexp ]] && echo match
Run Code Online (Sandbox Code Playgroud)

  • 你的 GNU `grep` 是否支持没有 `-P` 的 `\d`? (2认同)
  • 说 `\d` 或 PCRE 是“非标准的”是不公平的。它们非常标准,只是与原始正则表达式和扩展正则表达式的标准不同。 (2认同)
  • @DanielFarrell,这种情况下的标准是[POSIX 指定的内容](https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/basedefs/V1_chap09.html),它不知道`\d`。尽管您是对的,因为 PCRE 是相当标准的,或者至少是定义不明确的。令人讨厌的问题是 GNU grep(或 glibc)支持一些类似 PCRE 的原子,至少在解释 ERE 时支持 `\w` 和 `\s`,在这种情况下,它们非常_are_ 非标准的。我的措辞很可能部分来自于此,以及对 `\d` 同样受 GNU 支持的误解。 (2认同)

Sté*_*las 5

(:...)\d是 perl 或 PCRE 正则表达式运算符(如 GNU 中的grep -P)。

bash仅支持扩展正则表达式 in ,grep -E但对于按字面传递的正则表达式,如 in ,[[ text =~ regexp-here ]]而不是作为不带引号的扩展的结果(如 in[[ text =~ $var ]][[ test =~ $(printf '%s\n' 'regexp-here') ]]),它仅限于 POSIX 扩展正则表达式功能集。

因此,即使在grep -E '\d'可以工作的系统上(GNU ERE 已经从 perl 正则表达式导入了一些扩展,\s未来的版本也可能有\d),您也必须使用:

regexp='\d'
[[ $text =~ $regexp ]]
Run Code Online (Sandbox Code Playgroud)

让它bash工作([[ $text =~ \d ]]不会)。

对于支持 PCRE 的 shell,您可能需要改用zsh

set -o rematchpcre
[[ $text =~ '(?:\d{1,3}\.)+(?:\d{1,3})' ]]
Run Code Online (Sandbox Code Playgroud)

ksh93 还支持自己的类似 perl 正则表达式的实现(不完全兼容)作为其模式匹配的一部分。在那里,你可以使用:

regexp='~(P)(?:\d{1,3}\.)+(?:\d{1,3})'
[[ $text = $regexp ]]
Run Code Online (Sandbox Code Playgroud)

(请注意,=而不是=~。您将需要使用临时变量,因为如果不这样做,就会出现很多问题)