如何在.net正则表达式中找到不在括号内的逗号?

Posted

技术标签:

【中文标题】如何在.net正则表达式中找到不在括号内的逗号?【英文标题】:How to find a comma that is not inside parenthesis in a .net regular expression? 【发布时间】:2009-02-27 17:00:09 【问题描述】:

使用 .net 提供的一些扩展,可以通过以下方式找到括号组:

^(\w+)\(((?>[^()]+|\((?<D>)|\)(?<-D>))*(?(D)(?!)))\)(.*)$

这将匹配以下内容:

Func(innerfunction(arg)).DoSomething()

与以下组:

第 1 组:功能 第 2 组:内部函数(arg) 第 3 组:.DoSomething()

我的问题是,如何匹配逗号,考虑它们是否在括号组内?例如,要评估的正则表达式:

Func(innerFunction(arg1, arg2), arg3).DoSomething()

应该让步:

第 1 组:功能 第 2 组:innerFunction(arg1, arg2) 第 3 组:arg3 第 4 组:.DoSomething()

谢谢。

【问题讨论】:

【参考方案1】:

如果不想限制嵌套深度,单用正则表达式是不可能的。

因此,我建议您构建一个分解嵌套级别的解析器。逐个字符读取输入的字符。当是“(”时提高等级,当它是“)”时降低等级,当它是“,”时分裂。

【讨论】:

感谢您的建议。你能看看我的解决方案,看看有没有反例? +1。正则表达式无法处理任意深度的嵌套,需要其他类型的解析器。 我继续断言提出的解决方案可以解决问题。 计数策略解决了任意深度的嵌套问题:) 有什么反例吗?【参考方案2】:

虽然这并非不可能,但我建议不要为此使用正则表达式。

问题在于表达式往往要么完全贪婪,要么完全不贪婪。例如,采用以下输入:

(a,)b,(c,(d,)e,)

贪婪的表达式会尽可能匹配。它将看到 everything 在括号内,因此返回 nothing

不贪婪的表达式会正确匹配逗号 b,但它也会匹配逗号 e,因为它将(c,(d,) 视为一个完整的组。

现在,听起来您已经了解了这些问题,并且 .Net 正则表达式引擎确实具有可以让您在某种程度上克服这些问题的功能。但是结果表达式会很丑陋,难以维护,移植性不强,而且容易出错。除非您真的知道自己在做什么,否则最好寻找其他解决方案。

【讨论】:

【参考方案3】:

我想我找到了。谁有反例:

^([^()]*?|.*\((?>[^()]+|\((?<D>)|\)(?<-D>))*(?(D)(?!))\).*?),(.*)$

这将匹配这个表达式:

func1(arg2, func3(arg3, arg4)), func2(arg5, arg6).property

作为:

Group1:func1(arg2, func3(arg3, arg4)) Group2: func2(arg5, arg6).property

此解决方案仅查找一个逗号,但它处理任意深度的括号。

更新: Gumbo 提供了一个反例:

func1((arg1), arg2), func2(arg3).property

得到的分成:

Group1:func1((arg1) Group2:arg2)、func2(arg3).property

但是:通过将第一个“任意匹配”变为非贪婪,可以解决它:

^([^()]*?|.*?\((?>[^()]+|\((?<D>)|\)(?<-D>))*(?(D)(?!))\).*?)\s*,\s*(.+)$

还有其他反例吗?

【讨论】:

这是一个不匹配的例子:“func1((arg1), arg2), func2(arg3).property” get 被分成“func1((arg1)” 和 “arg2) , func2(arg3).property”(根据 regexlib.com/RETester.aspx>)。 这样的东西怎么样:“func1(")", arg1), func2().property”? Treating " 不在问题的范围内;没有任何意义。尽管如此,人们可以将它们视为 ()s。

以上是关于如何在.net正则表达式中找到不在括号内的逗号?的主要内容,如果未能解决你的问题,请参考以下文章

替换括号内的逗号

PHP 和 RegEx:用不在括号内的逗号(以及嵌套括号)拆分字符串

js正则表达式

JavaScript 正则

正则表达式 获取括号内的内容

如何使用正则表达式删除括号内的文本?