Bash =〜正则表达式和https://regex101.com/


12

我使用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

3
在我看来,这就像一个Perl正则表达式。Bash不支持。
Kusalananda

1
=~运营商讨论此手册中它是写Bash使用“扩展正则表达式”。扩展正则表达式在regex(7)手册页中进行了描述,并在此处进行了简要总结。
格伦·杰克曼

Answers:


15

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

但Bash不支持\d,因此您需要显式使用[0-9][[:digit:]]。同样对于非捕获组(?:..),只使用(..)来代替。

这应该打印match

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

2
请问您的GNU grep支持\d-P
斯特凡Chazelas

@StéphaneChazelas,哎呀,当然不是。它确实支持\wand \b,这是我从Perl那里学到的,所以我感到困惑。
ilkkachu

1
\dPCRE是“非标准的”是不公平的。它们是非常标准的,只是与原始正则表达式和扩展正则表达式不同的标准。
丹尼尔·法雷尔

1
@DanielFarrell,在这种情况下,标准是POSIX指定的,并且它不知道\d。尽管您说对了,但是PCRE是相当标准的,或者定义得最不明确。恼人的问题是,GNU的grep(或glibc的)支持一些PCRE样原子,至少\w\s解释ERE时,在这方面他们非常非标准。我的措辞很可能部分来自于此,以及\d类似的GNU支持的错误回忆。
ilkkachu

4

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

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

因此,即使在grep -E '\d'可以工作的系统上(GNU ERE已经从perl regexp导入了一些扩展,例如\s将来的版本也可能会引入\d),您也必须使用:

regexp='\d'
[[ $text =~ $regexp ]]

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

对于支持PCRE的Shell,您可能要zsh改用:

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

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

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

(请注意,=而不是=~。您将要使用临时变量,因为如果您不使用临时变量,则会出现很多错误)


1

该网站regex101.com默认使用PCRE(位于左上角),并且不支持“扩展”正则表达式语法。这就是Perl兼容的“ Perl兼容常规表达式”。

grep -P在某些情况下,某些工具(如)支持PCRE ,但该[[…]]习语内部的bash regex支持仅适用于扩展的regex(如grep -E)。

在扩展正则表达式中,(?…)不存在非括号,并且\ d也丢失。您需要使用simple (…)[0-9]

regexp="([0-9]{1,3}\.)+([0-9]{1,3})"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.