使用 .NET 正则表达式提取嵌套匹配括号之间的所有重叠子字符串

问题描述

我正在尝试解析带有嵌套括号的数学表达式:

(1 * (2 - 3)) + 4

我想把每个表达式都放在括号里,像这样:

  • (1 * (2 - 3))
  • (2 - 3)

使用这个表达式:(.*?\))(?=($|[^(]+)) 我得到这个结果:

(1 * (2 - 3)

)

使用这个表达式:\(.*?\) 我得到这个结果:

(1 * (2 - 3) 

但是没有任何东西可以正常工作。如何在内部循环表达式?

解决方法

你可以使用

(?=(\((?>[^()]+|(?<c>)\(|(?<-c>)\))*(?(c)(?!))\)))

参见regex demo详情

  • (?= - 一个积极的前瞻:
    • (\((?>[^()]+|(?<c>)\(|(?<-c>)\))*(?(c)(?!))\))) - 第 1 组:
      • \( - ( 字符
      • (?>[^()]+|(?<c>)\(|(?<-c>)\))* - 除 ()( 字符以外的任何一个或多个字符的零次或多次重复(将值推入组“c " 堆栈),或 ) 字符(具有从 Group "c" 堆栈中弹出的值)
      • (?(c)(?!)) - 如果“c”组堆栈不为空,则失败并回溯
      • \) - 一个 ) 字符。

C# demo

var text = "(1 * (2 - 3)) + 4";
var pattern = @"(?=(\((?>[^()]+|(?<c>)\(|(?<-c>)\))*(?(c)(?!))\)))";
var results = Regex.Matches(text,pattern)
    .Cast<Match>()
    .Select(m => m.Groups[1].Value)
    .ToList();
Console.WriteLine(String.Join(",",results));
// => (1 * (2 - 3)),(2 - 3)
,

通常的方法是使用 recursive regular expression,但不幸的是,C# 的 Regex 不支持此功能。或者,您可以手动解析字符串(并且提供了 C# 代码 in this PAQ 来执行此操作)。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...