如何在匹配表达式中编写正则表达式文字?

kjo*_*kjo 6 scripting bash shell-script regular-expression syntax

这个问题是关于在 bash 下的匹配表达式中编写正则表达式文字的正确方法。

在 zsh 中,下面的匹配成功了,正如我所料:

% [[ ' 123 ' =~ '^ [0-9]+ $' ]]; echo $?
0
Run Code Online (Sandbox Code Playgroud)

在 bash 中并非如此:

$ [[ ' 123 ' =~ '^ [0-9]+ $' ]]; echo $?
1
Run Code Online (Sandbox Code Playgroud)

我知道这场比赛在 bash 中成功

$ ( regexp='^ [0-9]+ $'; [[ ' 123 ' =~ $regexp ]]; echo $? )
0
Run Code Online (Sandbox Code Playgroud)

...但它需要将正则表达式分配给一个中间变量。


我的问题是:如何在 bash 下的匹配表达式中编写任意正则表达式文字

jes*_*e_b 8

最好按照 Bash 参考手册3.2.4.2 Conditional Constructs 的建议将其放入变量中:

将正则表达式存储在 shell 变量中通常是避免引用 shell 特殊字符时出现问题的有用方法。有时很难在不使用引号的情况下从字面上指定正则表达式,或者在注意 shell 的引号删除时跟踪正则表达式使用的引号。使用 shell 变量来存储模式可以减少这些问题。

但是,为了直接在 bash 扩展测试中编写它,您需要删除引号并转义空格:

$ [[ ' 123 ' =~ ^\ [0-9]+\ $ ]]; echo $?
0
Run Code Online (Sandbox Code Playgroud)


小智 5

在 bash 中,规范的答案是:使用 var

$ reg='^ [0-9]+ $'
$ [[ ' 123 ' =~ $reg ]]; echo $?
Run Code Online (Sandbox Code Playgroud)

这适用于空格、反斜杠和许多其他东西:

$ reg='^ 12\3 $'
$ [[ ' 12\3 ' =~ $reg ]]; echo $?
0
Run Code Online (Sandbox Code Playgroud)

如果你想把它写成文字,你需要(小心)引用。
您需要引用需要文字的部分,并保留应解释为正则表达式的部分不加引号。空间需要引用。这里使用反斜杠:

$ [[ ' 123 ' =~ ^\ [0-9]+\ $ ]]; echo $?
0
Run Code Online (Sandbox Code Playgroud)

这里使用双引号:

$ [[ ' 123 ' =~ ^" "[0-9]+" "$ ]]; echo $?
Run Code Online (Sandbox Code Playgroud)

但是“引用”会因为反斜杠之类的东西而变得非常混乱:

$ [[ ' 12\3 ' =~ ^" "[0-9]+"\\"[0-9]+" "$ ]]; echo $?
0
Run Code Online (Sandbox Code Playgroud)

更简单、更安全:

$ reg='^ [0-9]+\\[0-9]+ $'
$ [[ ' 12\3 ' =~ $reg ]]; echo $?
0
Run Code Online (Sandbox Code Playgroud)

而且,不,您不需要子 shell 来执行此操作(问题中的括号)。

$ reg='^ [0-9]+\\[0-9]+ $'; [[ ' 12\3 ' =~ $reg ]]; echo $?
Run Code Online (Sandbox Code Playgroud)

是的,这可能看起来很烦人。是的,您提供的命令恰好可以在 zsh 中运行:

$ [[ ' 123 ' =~ '^ [0-9]+ $' ]]; echo $?
0
Run Code Online (Sandbox Code Playgroud)

但引用总是一个问题(在任何 shell 中),反斜杠会发生什么?:

% [[ ' 12\3 ' =~ ' 12\3 ' ]]; echo $?
zsh: failed to compile regex: Invalid back reference
1


% [[ ' 12\3 ' =~ '^ [0-9]+\\3 $' ]]; echo $?
0
Run Code Online (Sandbox Code Playgroud)

加倍!它不完全是:字面意思