使用负前瞻错误返回 2 的 Bash 双括号正则表达式比较

Ric*_*Liu 3 regex bash negative-lookahead square-bracket

在 Bash 4.1 机器上,

我正在尝试使用“双括号[[ expression ]]来使用“ NEGATIVE LOOKAHEAD ”进行正则表达式比较。

我做了“ set +H”来禁用 BASH 变量' !'扩展命令历史搜索。

我想匹配“任何字符串”,除了“ arm-trusted-firmware ”。

set +H
if [[ alsa  =~ ^(?!arm-trusted-firmware).* ]]; then echo MATCH; else echo "NOT MATCH"; fi
Run Code Online (Sandbox Code Playgroud)

我希望这会打印“MATCH”,但它会打印“NOT MATCH”。

查看“双括号”的返回码后,它返回“2”:

set +H
[[ alsa  =~ ^(?!arm-trusted-firmware).* ]]
echo $?
Run Code Online (Sandbox Code Playgroud)

根据 bash 手册,返回值 '2' 表示“正则表达式在语法上不正确”:

可以使用额外的二元运算符 =~,其优先级与 == 和 != 相同。
使用时,运算符右侧的字符串被视为扩展正则表达式并进行相应匹配(如 regex(3) 中所示)。
如果字符串与模式匹配,则返回值为 0,否则为 1。如果正则表达式在语法上不正确,则条件表达式的返回值为 2。

我做错了什么?

在我的原始脚本中,我正在与 STRING 列表进行比较。

当它匹配时,我触发一些函数调用;

当它不匹配时,我会跳过我的动作。

所以,是的,从这个例子中,

我正在比较“alsa”和“arm-trusted-firmware”之间的字符串。

Sam*_*uel 6

默认情况下,bash POSIX 标准不支持 PCRE。(来源:Wiki Bash 黑客

作为解决方法,您需要启用extglob. 这将启用一些扩展的全局模式:

$ shopt -s extglob
Run Code Online (Sandbox Code Playgroud)

查看Wooledge Wiki以了解更多关于extglob.

然后你就可以使用这样的模式:

?(pattern-list)   Matches zero or one occurrence of the given patterns
*(pattern-list)   Matches zero or more occurrences of the given patterns
+(pattern-list)   Matches one or more occurrences of the given patterns
@(pattern-list)   Matches one of the given patterns
!(pattern-list)   Matches anything except one of the given patterns
Run Code Online (Sandbox Code Playgroud)

更多关于Wiki Bash HackersLinuxJournal 的扩展 BASH globbing 的信息

  • 你想说什么?该部分解释了模式匹配,也称为通配符,而不是正则表达式。这就是为什么启用它的选项称为`extglob`。 (4认同)
  • 感谢这个作品~ `shopt -s extglob` `if [[ alsa == !(arm-trusted-firmware) ]]; 然后回声匹配;否则回声“不匹配”;fi`:这个**匹配**。`if [[ arm-trusted-firmware == !(arm-trusted-firmware) ]]; 然后回声匹配;否则回声“不匹配”;fi`:这个**不匹配**。 (2认同)
  • 我没有投反对票,但您似乎混淆了通配符和正则表达式。 (2认同)

Ric*_*Liu 5

感谢@Barmar 的回答

BASH不支持“环视”(lookaheadlookbehind

bash不使用PCRE,也不支持环视