【问题标题】:Matching balanced parentheses before a character匹配字符前的平衡括号
【发布时间】:2018-05-28 06:09:33
【问题描述】:

我需要在 c# 中的文字句点之前匹配括号内的字符串。当字符串中有额外的开放括号时,我的平衡组正则表达式可以工作 except。根据我的理解,这需要一个条件失败模式来确保堆栈在匹配时为空,但有些地方不太对。

原始正则表达式:

@"(?<Par>[(]).+(?<-Par>[)])\."

使用失败模式:

@"(?<Par>[(]).+(?<-Par>[)])(?(Par)(?!))\."

测试代码(最后 2 个失败):

string[] tests = {
    "a.c",   "",
    "a).c",  "",
    "(a.c",  "",
    "a(a).c", "(a).",
    "a(a b).c", "(a b).",
    "a((a b)).c", "((a b)).",
    "a(((a b))).c", "(((a b))).",
    "a((a) (b)).c", "((a) (b)).",
    "a((a)(b)).c", "((a)(b)).",
    "a((ab)).c", "((ab)).",
    "a)((ab)).(c", "((ab)).",
    "a(((a b)).c", "((a b)).", 
    "a(((a b)).)c", "((a b))."
};

Regex re = new Regex(@"(?<Par>[(]).+(?<-Par>[)])(?(Par)(?!))\.");

for (int i = 0; i < tests.Length; i += 2)
{
    var result = re.Match(tests[i]).Groups[0].Value;
    if (result != tests[i + 1]) throw new Exception
        ("Expecting: " + tests[i + 1] + ", got " + result);
}

【问题讨论】:

标签: c# regex balanced-groups


【解决方案1】:

您可以使用众所周知的正则表达式来匹配平衡括号,并在其上附加一个\.

\((?>[^()]+|(?<o>)\(|(?<-o>)\))*(?(o)(?!))\)\.
|---------- balanced parens part ----------|.|

请参阅regex demo

详情

  • \( - 一个(
  • (?&gt; - 原子组的开始
    • [^()]+ - 除() 之外的1 个或多个字符
    • | - 或
    • (?&lt;o&gt;)\( - 一个开口 ( 被推送到组 o 堆栈
    • | - 或
    • (?&lt;-o&gt;)\) - 关闭 ( 从组中弹出 o 堆栈
  • )* - 原子组的 0 次或多次重复
  • (?(o)(?!)) - 如果组 o 堆栈不为空,则匹配失败
  • \) - 一个)
  • \. - 一个点。

【讨论】:

  • 刚刚在 RegexHero.net 进行了测试,如果将 \(\) 包含在“o”组中,该模式的运行速度会更快:\((?&gt;[^()]+|(?&lt;o&gt;\()|(?&lt;-o&gt;\)))*(?(o)(?!))\)\.
猜你喜欢
  • 1970-01-01
  • 2011-12-15
  • 2016-06-03
  • 2021-03-06
  • 2010-10-07
相关资源
最近更新 更多