Bash中的非理性REGEX模式匹配

时间:2015-12-23 22:52:05

标签: regex bash

guest@porteus:~$ [[ "libSDL_image-1.2.so.0.8.4" =~ ^.*[.]so(([.][0-9]+)+)*$ ]] && echo LIB
LIB
guest@porteus:~$ echo ${#BASH_REMATCH[*]}
3
guest@porteus:~$ echo ${BASH_REMATCH[1]}
.0.8.4
guest@porteus:~$ echo ${BASH_REMATCH[2]}
.4

可以检索正则表达式和库版本。

guest@porteus:~$ [[ "libSDL_image-1.2.so.0.8.4" =~ ^.*[.]so(([.][0-9]+)+)*$|^lib.+[.]so.* ]] && echo LIB
LIB
guest@porteus:~$ echo ${#BASH_REMATCH[*]}
3
guest@porteus:~$ echo "'${BASH_REMATCH[1]}'"
''
guest@porteus:~$ echo "'${BASH_REMATCH[2]}'"
''

匹配,但版本无法恢复。

guest@porteus:~$ [[ "libSDL_image-1.2.so.0.8.4" =~ ^.*[.]so(([.][0-9]+)+)*$|^lib.+[.]so(.*) ]] && echo LIB
LIB
guest@porteus:~$ echo ${#BASH_REMATCH[*]}
4
guest@porteus:~$ echo "'${BASH_REMATCH[1]}'"
''
guest@porteus:~$ echo "'${BASH_REMATCH[2]}'"
''
guest@porteus:~$ echo "'${BASH_REMATCH[3]}'"
'.0.8.4'

版本现在只能从备用正则表达式匹配中检索。

问题是为什么第一场比赛被忽略了,有没有办法告诉替代方案何时不按顺序匹配?

1 个答案:

答案 0 :(得分:1)

Posix没有在交替中指定模式之间的任何偏好(即以 | 为主要运算符的正则表达式模式。)

Posix要求:

  • 整体匹配是从最左边位置开始的可能匹配中最长的匹配。

  • 每个子模式,从左到右,尽可能长,在剩余的可能性范围内。

这与(传统的)Perl和ECMAscript完全不同,后者要求按顺序尝试替换,并且替代方案的成功优先于以下替代方案,即使以下替代方案会更长。

这只是定义正则表达式匹配的两种方法。我认为两者都不是更“理性”;每个人都有充分的论据支持和反对,最终需要选择一个。

Posix模型更接近常规语言的数学模型,因为它值得。

如果交替中的两个备选项都匹配相同的字符串,则必须选择一个。由实现决定哪个,并且由于未指定,它可能会随版本而变化。

您最好的选择是允许使用任一捕获。例如(使用你的第三个例子):

version=${BASH_REMATCH[2]:-${BASH_REMATCH[3]}}