在我的OS X 10.5.8机器上,使用regcomp和regexec C函数匹配扩展的正则表达式“(()| abc)xyz”,我找到匹配字符串“abcxyz”,但只能从偏移量3到我期望整个字符串匹配,我会看到字符串的初始“abc”部分的子匹配。
当我在同一台机器上使用awk尝试相同的模式和文本时,它会像我期望的那样显示整个字符串的匹配。
我希望我对正则表达式的有限经验可能是个问题。有人可以解释发生了什么吗?我的正则表达式有效吗?如果是这样,为什么它不匹配整个字符串?
我理解“((abc){0,1})xyz”可以作为替代,但感兴趣的模式是从另一种模式格式自动生成的,并且消除“()”的实例是额外的工作我想尽可能避免。
作为参考,我传递给regcomp的标志只包含REG_EXTENDED。我将一组空标志(0)传递给regexec。
答案 0 :(得分:2)
POSIX标准说:
9.4.3 ERE特殊字符
ERE特殊字符在某些上下文中具有特殊属性。在这些上下文之外,或者在
<backslash>
之前,这样的字符应该是与特殊字符本身匹配的ERE。扩展正则表达式特殊字符及其具有特殊含义的上下文如下:
.[\(
<period>
,<left-square-bracket>
,<backslash>
和<left-parenthesis>
应该是特殊的,除非在括号表达式中使用(请参阅RE括号表达式)。在括号表达式之外,<left-parenthesis>
后面紧跟<right-parenthesis>
会产生未定义的结果。
您所看到的是调用未定义行为的结果 - 任何事情都会发生。
如果您想获得可靠,便携的结果,则必须删除空的“()
”符号。
答案 1 :(得分:0)
如果你遍历所有匹配,并且没有同时获得[3,6]和[0,6],那么就有一个错误。我不确定posix要求返回匹配的顺序。
答案 2 :(得分:0)
尝试(abc|())xyz
- 我打赌它会在两个地方产生相同的结果。我只能假设C版本试图在任何可能的地方匹配xyz
,如果失败,它会尽可能地匹配abcxyz
(但是,如你所见,它不会失败) ,所以我们从不打扰“abc”部分)而awk
必须使用它自己的正则表达式引擎,以你预期的方式执行。
你的正则表达式是有效的。我认为问题是a)POSIX不是很清楚正则表达式应该如何工作,或者b)awk
没有使用100%POSIX兼容的正则表达式(可能是因为OS X出现了更多原始版本awk
)。无论遇到什么问题,都可能是因为这有点像边缘情况,大多数人都不会这样写正则表达式。