如何在shell脚本中使用正则表达式?

Jér*_*e G 25 regex bash shell

我试图在shell脚本中匹配字符串与正则表达式.这个字符串是脚本的参数($ 1),它是一个日期(MM/DD/YYYY)我正在尝试使用的正则表达式是:

^\d{2}[\/\-]\d{2}[\/\-]\d{4}$
Run Code Online (Sandbox Code Playgroud)

它似乎工作,我在几个正则表达式测试网站上尝试过.

我的shell代码是:

REGEX_DATE="^\d{2}[\/\-]\d{2}[\/\-]\d{4}$"
 
echo "$1" | grep -q $REGEX_DATE
echo $?
Run Code Online (Sandbox Code Playgroud)

"echo $?" 返回1,不管是我放入参数的字符串.

你们有个主意吗?

谢谢 !

mkl*_*nt0 47

为了补充现有的有用答案:

在这种情况下,使用Bash自己的正则表达式匹配运算符=~是一种更快的替代方法,因为您只匹配已存储在变量中的单个值:

set -- '12-34-5678' # set $1 to sample value

kREGEX_DATE='^[0-9]{2}[-/][0-9]{2}[-/][0-9]{4}$' # note use of [0-9] to avoid \d
[[ $1 =~ $kREGEX_DATE ]]
echo $? # 0 with the sample value, i.e., a successful match
Run Code Online (Sandbox Code Playgroud)

但请注意,使用特定于特定风格的正则表达式构造\d警告同样适用:虽然=~支持ERE(扩展正则表达式),但它也支持主机平台的特定扩展 - 这是Bash行为与平台相关的罕见情况.

为了保持便携性(在Bash的上下文中),请坚持POSIX ERE规范.

请注意,=~甚至允许您定义捕获组(带括号的子表达式),这些捕获组的匹配可以在以后通过Bash的特殊${BASH_REMATCH[@]}数组变量访问.

附加说明:

  • $kREGEX_DATE使用不带引号,这是正则表达式被识别的必要条件(引用的部分将被视为文字).

  • 虽然不总是必要的,最好是先存储在一个变量正则表达式,因为Bash有与正则表达式的麻烦文字包含\.

    • 例如,在Linux上,\<支持匹配字边界的地方[[ 3 =~ \<3 ]] && echo yes不起作用,但re='\<3'; [[ 3 =~ $re ]] && echo yes确实如此.
  • 我已将变量名更改REGEX_DATEkREGEX_DATE(k表示(概念)常量),以确保名称不是全大写名称,因为应避免使用全大写变量名以防止与特殊环境和shell变量冲突.


Chr*_*ear 13

我想这就是你想要的:

REGEX_DATE='^\d{2}[/-]\d{2}[/-]\d{4}$'

echo "$1" | grep -P -q $REGEX_DATE
echo $?
Run Code Online (Sandbox Code Playgroud)

我用-P开关来获取perl正则表达式.

  • 只是为了澄清,并不保证所有发行版都支持`-P`.因此,如果可移植性是一个问题,你会想要避免它. (3认同)

Mik*_*ger 6

问题是你正在尝试使用grep不支持的正则表达式功能.即,你\d不会工作.改用它:

REGEX_DATE="^[[:digit:]]{2}[-/][[:digit:]]{2}[-/][[:digit:]]{4}$"
echo "$1" | grep -qE "${REGEX_DATE}"
echo $?
Run Code Online (Sandbox Code Playgroud)

你需要-E国旗来获得ERE才能使用{#}风格.