OSX 和 Linux 上的 Bash RegEx(奇怪之处)

OSX 和 Linux 上的 Bash RegEx(奇怪之处)

这是关于 Bash 开发和编码使用 RegEx 的可移植 Bash 脚本

在 Mac 上使用 Bash RegEx,我可以执行以下操作:

coconut-mac$ a='bananacoconutman'; [[ "$a" =~ banana(.*?)man ]] && echo FOUND ${BASH_REMATCH[1]}
FOUND coconut

很好。在很多地方都很有用。喜欢。

当我尝试这样做时,它失败了:

coconut-mac$ a='<title>coconut</title>'; [[ "$a" =~ \<title\>(.*?)\</title\> ]] && echo FOUND ${BASH_REMATCH[1]}

精确的运行相同的命令完美关于企鹅:

coconut-linux$ a='<title>coconut</title>'; [[ "$a" =~ \<title\>(.*?)\</title\> ]] && echo FOUND ${BASH_REMATCH[1]}
FOUND coconut
  • 为什么?
  • 如何修复它以使脚本可移植?

编辑:在 Mac 上:

OS X version: 10.8.2
Bash version: 4.2.37(2)-release

在 Ubuntu 12.04 LTS 上:

Linux kernel version: 3.2.0-29-generic-pae
Linux version: Ubuntu 12.04.1 LTS
Bash version: 4.2.24(1)-release

答案1

在我的 Mac 上,info bash / =~ RET显示:

附加二元运算符=~', is available, with the same precedence as==' 和 `!='。使用时,运算符右侧的字符串被视为扩展正则表达式并进行相应匹配(如 regex3))。

man 3 regex说:

重复运算符(?',*'、+', or bounds) cannot follow another repetition operator. A repetition operator cannot begin an expression or subexpression or follow^' 或 '|')。

man 3 regex我在 GNU regex或中没有看到任何类似的文档info regex

?如果我从您的中删除(.*?)并执行以下操作,它将在两个操作系统上运行:

$ a='<title>coconut</title>'; [[ "$a" =~ \<title\>(.*)\</title\> ]] && echo FOUND ${BASH_REMATCH[1]}
FOUND coconut

答案2

这可能是答案:

Darwin(10.8.1/2)上的默认 bash:

GNU bash, version 3.2.48(1)-release (x86_64-apple-darwin12)

例如,Ubuntu 12 LTS 上的默认 bash:

GNU bash, version 4.2.24(1)-release (x86_64-pc-linux-gnu)

使其可移植将会远离较新的 bash 怪癖并使用诸如sed、、awk等等之类的东西。

相关内容