【问题标题】:Regular Expression to disambiguate between arbitrary parenthesis and an optional trailing parenthesis construct containing comma delimited arguments正则表达式消除任意括号和包含逗号分隔参数的可选尾括号构造之间的歧义
【发布时间】:2011-12-06 12:11:02
【问题描述】:

我在编写正则表达式时遇到了一些问题,我很想修改正则表达式语法的所有语言元素,但遗憾的是我在这个特定的工作项目上的时间不多了,所以我不得不听从那里更强大的正则表达式大师:)

平台

这是使用 .NET 正则表达式引擎运行的。到目前为止,我已经使用 Expresso 创建了模式。

目前的模式

^ (? (?#这里的量词简直太贪心了,我还以为只是个懒人 修饰符“?”合适吗?) (?# 但是我不得不用积极的眼光来哄它 断言???懒人 '*?'对它自己感到困惑的Expresso?) .*?(?=\([^(]+\)$|$) ) (?# 如果有逗号分隔的参数,则处理前导逗号) (\(\s*(\s*,?\s* (?# 所有这些参数都是可选的,但至少其中一个必须 存在以将尾随括号限定为参数) (C\s*=\s*(?\d{4}) |B\s*=\s*(?\d{4}) |S\s*=\s*(?[\d.]+)\s*%?\s* |P\s*=\s*(?[^,]+) |U\s*=\s*(?[\d.]+)\s*%?\s*))* (?# 这个零或一个量词需要比 BaseTable 更贪心 量词) \))?

测试用例

PA(90)M(S=125.00 %,B=2011) PA(90)M(S=125.00 %) PA(90)中号 PA(90)M(S=125.00 %,B=2011) 表(任意表括号)(p=参数,s=125.00%) BaseTable(TableDetail)(B=2011,P=ProjectionArguments,S=115.00%,U=5.00%) BaseTable(TableDetail)( B = 2011 , P = ProjectionArguments , S = 115.00 %, U = 5.00 %) 基表(带空格)(B = 2011,P = ProjectionArguments,S = 115.00 %,U = 5.00 %) 仅(ASuccessfulMatch)(S=125.00 %,P = CMI_2009_F [1.25%] + 1.25%) 仅(部分匹配)

问题

除了最后一个之外,以上所有都产生了很好的匹配。我需要将整个最后一个案例Only(APartialMatch) 全部包含在命名的捕获组BaseTable 中。

Only(APartialMatch) 需要与上一个匹配项 Only(ASuccessfulMatch) 消除歧义。

非常感谢任何帮助!干杯!

更新

jsobo 提供了一个修正的正则表达式模式,推动了解决方案的发展。它只解释了尾随括号之前的一对任意括号 - 最终是我如何构建调查的缺陷(许多道歉)。我希望对模式进行修正,以明确区分包含参数的尾随括号对和BaseTable 子捕获中可能存在的任何其他括号。

因此,一些更新的测试用例将是:

基表(带空格)表格资料(更多表格资料)(B = 2011,P = ProjectionArguments,S = 115.00 %,U = 5.00 %) 基表(带空格)表材料(更多表材料)其他表材料(还有更多表材料)(B = 2011,P = ProjectionArguments,S = 115.00 %,U = 5.00 %) 基表(带空格)表材料(更多表材料)其他表材料(还有更多表材料)最终基表材料(B = 2011,P = ProjectionArguments,S = 115.00 %,U = 5.00 %)

【问题讨论】:

    标签: .net regex


    【解决方案1】:

    我在第一组中去掉了你的前瞻性,只是改变了它来寻找你的模式

    anything...(anything)在下一个括号之前可选更多的东西...

    ^(?<BaseTable>.*?\(.*?\)[^(]*)(\(\s*(\s*,?\s*(C\s*=\s*(?<CalenderYear>\d{4})|B\s*=\s*(?<YearOfBirth>\d{4})|S\s*=\s*(?<Scale>[\d.]+)\s*%?\s*|P\s*=\s*(?<Projection>[^,]+)|U\s*=\s*(?<Underpin>[\d.]+)\s*%?\s*))*\))?
    

    所以

    ^(?<BaseTable>.*?(?=\([^(]+\)$|$)))
    

    成为

    ^(?<BaseTable>.*?\(.*?\)[^(]*)
    

    【讨论】:

    • 我没有查看正则表达式的其余部分(详细),但它看起来像你想要的。注意:没有日历年的测试用例...
    • 你是对的......没有测试用例,但在交替构造的上下文中,我并不太大惊小怪!我跑了你的表情,它匹配。打的好!!!我会破译您的修改以感谢您的调整,非常感谢。
    • 感谢您的提交,很接近,我已经更新了问题,正如您所指出的,缺少一些测试用例。我不太担心交替构造的问题,但在最后一对括号之前存在任意对括号的数量问题。
    • 是“BASETABLE”捕获组是否应该在最后一组 Parens 之前完成所有操作?
    • 是的,只有最后一组括号包含一个参数列表,如交替构造中所述的详细说明键值对的键值对,其中键等于 C、B、S、P 或 U。否则,最后一组括号也应被视为BaseTable 子捕获的一部分。我无法完全绕开它......感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-15
    • 1970-01-01
    • 2015-10-05
    • 1970-01-01
    • 1970-01-01
    • 2021-10-05
    相关资源
    最近更新 更多