使用 .NET 正则表达式提取嵌套匹配括号之间的所有重叠子字符串
Extracting all overlapping substrings between nested matching parentheses with a .NET regex
我正在尝试解析带嵌套括号的数学表达式:
(1 * (2 - 3)) + 4
我想得到方括号中的每个表达式,像这样:
(1 * (2 - 3))
(2 - 3)
使用这个表达式:(.*?\))(?=($|[^(]+))
我得到这个结果:
(1 * (2 - 3)
)
并使用这个表达式:\(.*?\)
我得到这个结果:
(1 * (2 - 3)
但没有任何工作正常。如何在内部循环表达式?
通常的方法是使用 recursive regular expression but unfortunately this capability is not supported by C#'s Regex. Alternatively, you can manually parse the string (and there is C# code provided in this PAQ 来做到这一点。
您可以使用
(?=(\((?>[^()]+|(?<c>)\(|(?<-c>)\))*(?(c)(?!))\)))
见regex demo。 详情:
(?=
- 正面前瞻:
(\((?>[^()]+|(?<c>)\(|(?<-c>)\))*(?(c)(?!))\)))
- 第 1 组:
\(
- 一个 (
字符
(?>[^()]+|(?<c>)\(|(?<-c>)\))*
- 除 (
和 )
之外的任何一个或多个字符的零次或多次重复,或 (
字符(将值推送到组"c" 堆栈)或 )
字符(从组 "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)
我正在尝试解析带嵌套括号的数学表达式:
(1 * (2 - 3)) + 4
我想得到方括号中的每个表达式,像这样:
(1 * (2 - 3))
(2 - 3)
使用这个表达式:(.*?\))(?=($|[^(]+))
我得到这个结果:
(1 * (2 - 3)
)
并使用这个表达式:\(.*?\)
我得到这个结果:
(1 * (2 - 3)
但没有任何工作正常。如何在内部循环表达式?
通常的方法是使用 recursive regular expression but unfortunately this capability is not supported by C#'s Regex. Alternatively, you can manually parse the string (and there is C# code provided in this PAQ 来做到这一点。
您可以使用
(?=(\((?>[^()]+|(?<c>)\(|(?<-c>)\))*(?(c)(?!))\)))
见regex demo。 详情:
(?=
- 正面前瞻:(\((?>[^()]+|(?<c>)\(|(?<-c>)\))*(?(c)(?!))\)))
- 第 1 组:\(
- 一个(
字符(?>[^()]+|(?<c>)\(|(?<-c>)\))*
- 除(
和)
之外的任何一个或多个字符的零次或多次重复,或(
字符(将值推送到组"c" 堆栈)或)
字符(从组 "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)