我正试图制作一个正则表达式来捕获一个函数样式参数列表,它应该是直截了当的,但是我遇到了一个我不理解的行为。
在下面的代码片段中,第一个示例的行为正如您所期望的那样,将函数名称捕获到第一个组中,将参数列表捕获到第二个组中。
在第二个例子中,我想用'一个或多个'量词替换用于捕获参数列表的'零个或多个'量词,这样如果没有参数,第二个组将失败。我期待正则表达式只捕获函数名称,但由于某种原因,正则表达式正在使用函数名称末尾的'1',我不能为我的生活看到为什么会这样做。请问有谁能看到这个问题吗?
// {func1} {blah, blah, blah}
Match m13 = Regex.Match("func1(blah, blah, blah)", @"(\w+) (?([(]) [(]([^)]*) )",
RegexOptions.IgnorePatternWhitespace | RegexOptions.IgnoreCase);
// {func}
Match m14 = Regex.Match("func1()", @"(\w+) (?([(]) [(]([^)]+) )",
RegexOptions.IgnorePatternWhitespace | RegexOptions.IgnoreCase);
答案 0 :(得分:1)
您的表情可以调整为:
(\w+) (?([(]) [(]([^)]*) )
^ rather than +
表达式返回意外结果的原因与回溯有关。正则表达式引擎有效地采取以下步骤:
(\w)
匹配func1
。func1
后面紧跟一个(
,匹配条件匹配结构中的零宽度表达式。(
字面值,后跟一个或多个不是)
的字符。 此条件因输入func1()
而失败,因为(
和)
之间的字符为零。 (\w)
现在匹配func
而不是func1
。func
后面紧跟一个1
,它不满足条件匹配结构中的零宽度表达式。func
,而在第二个捕获的组中没有匹配。问题出现在第3步中,其中表达式无法允许()
作为合法参数列表。调整表达式以允许在开括号和右括号之间使用零字符(如上所示)允许此序列。诸如^(\w+)(?:\((.*)\))?$
之类的表达式也可以在不需要条件构造的情况下解决潜在问题。