在我的OS X 10.5.8机器上,使用regcomp和regexec C函数匹配扩展的正则表达式<!>“(()| abc)xyz <!>”;我找到匹配的字符串< !> QUOT;!abcxyz <> QUOT;但是只能从偏移3到偏移6.我期望整个字符串匹配,我会看到初始<!>“abc <!>”的子匹配;字符串的一部分。

当我在同一台机器上使用awk尝试相同的模式和文本时,它会像我期望的那样显示整个字符串的匹配。

我希望我对正则表达式的有限经验可能是个问题。有人可以解释发生了什么吗?我的正则表达式有效吗?如果是这样,为什么它不匹配整个字符串?

我理解<!>“;((abc){0,1})xyz <!> quot;可以用作替代方案,但感兴趣的模式是从另一种模式格式自动生成的,并且消除了<!>“;()<!>”的实例。如果可能的话,我想避免额外的工作。

作为参考,我传递给regcomp的标志只包含REG_EXTENDED。我将一组空标志(0)传递给regexec。

有帮助吗?

解决方案

POSIX 标准说:

  

9.4.3 ERE特殊字符

     

ERE特殊字符在某些上下文中具有特殊属性。在这些上下文之外,或者在<backslash>之前,这样的字符应该是与特殊字符本身匹配的ERE。扩展正则表达式特殊字符及其具有特殊含义的上下文如下:

     

.[\(

     

<period><left-square-bracket><left-parenthesis><right-parenthesis>应该是特殊的,除非在括号表达式中使用(请参阅RE括号表达式)。在括号表达式之外,()后面跟着<=>会产生未定义的结果。

您所看到的是调用未定义行为的结果 - 任何事情都会发生。

如果您想要可靠,便携的结果,则必须删除空的“<=>”符号。

其他提示

如果你遍历所有匹配,并且没有同时获得[3,6]和[0,6],那么就有一个错误。我不确定posix要求返回匹配的顺序。

尝试(abc|())xyz - 我打赌它会在两个地方产生相同的结果。我只能假设C版本试图匹配xyz,无论它在哪里,如果失败,它会尝试匹配abcxyz任何地方(但是,如你所见,它不会失败,所以我们永远不会打扰<!>“; abc <!>”;部分)而awk必须使用它自己的正则表达式引擎,它按照你期望的方式运行。

你的正则表达式是有效的。我认为问题是:a)POSIX不是很清楚正则表达式应该如何工作,或者b)<=>没有使用100%符合POSIX标准的正则表达式(可能是因为它看起来OS X附带了更原始的版本of <=>)。无论遇到什么问题,都可能是因为这有点像边缘情况,大多数人都不会这样写正则表达式。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top