Regex与平衡组

本文关键字:平衡 Regex | 更新日期: 2023-09-27 17:59:38

我需要编写regex,以捕获类型名称的泛型参数(也可以是泛型参数),并使用如下特殊表示法:

System.Action[Int32,Dictionary[Int32,Int32],Int32]

假设类型名称为['w.]+,参数为['w.,'[']]+所以我只需要获取Int32Dictionary[Int32,Int32]Int32

基本上,如果平衡组堆栈为空,我需要采取一些措施,但我真的不明白该怎么做。

UPD

下面的答案帮助我快速解决了这个问题(但没有经过适当的验证,深度限制为1),但我已经通过组平衡做到了:

^['w.]+                                              #Type name
'[(?<delim>)                                         #Opening bracet and first delimiter
['w.]+                                               #Minimal content
(
['w.]+                                                       
((?(open)|(?<param-delim>)),(?(open)|(?<delim>)))*   #Cutting param if balanced before comma and placing delimiter
((?<open>'[))*                                       #Counting [
((?<-open>']))*                                      #Counting ]
)*
(?(open)|(?<param-delim>))']                         #Cutting last param if balanced
(?(open)(?!)                                         #Checking balance
)$

演示

UPD2(上次优化)

^['w.]+
'[(?<delim>)
['w.]+
(?:
 (?:(?(open)|(?<param-delim>)),(?(open)|(?<delim>))['w.]+)?
 (?:(?<open>'[)['w.]+)?
 (?:(?<-open>']))*
)*
(?(open)|(?<param-delim>))']
(?(open)(?!)
)$

Regex与平衡组

我建议使用捕获这些值

'w+(?:'.'w+)*'[(?:,?(?<res>'w+(?:'[[^][]*])?))*

请参阅regex演示。

详细信息:

  • 'w+(?:'.'w+)*-匹配1个以上单词字符,后跟.+1个以上字符1次或多次
  • '[-文字[
  • (?:,?(?<res>'w+(?:'[[^][]*])?))*-0个或多个序列:
    • ,?-可选逗号
    • (?<res>'w+(?:'[[^][]*])?)-组"res"捕获:
      • 'w+-一个或多个单词字符(也许,您想要['w.]+
      • (?:'[[^][]*])?-1或0(将?更改为*以匹配1个或多个)[、除[]之外的0+个字符以及闭合]的序列

下面的C#演示:

var line = "System.Action[Int32,Dictionary[Int32,Int32],Int32]";
var pattern = @"'w+(?:'.'w+)*'[(?:,?(?<res>'w+(?:'[[^][]*])?))*";
var result = Regex.Matches(line, pattern)
        .Cast<Match>()
        .SelectMany(x => x.Groups["res"].Captures.Cast<Capture>()
            .Select(t => t.Value))
        .ToList();
foreach (var s in result) // DEMO
    Console.WriteLine(s);

更新:要考虑未知深度的[...]子字符串,请使用

'w+(?:'.'w+)*'[(?:'s*,?'s*(?<res>'w+(?:'[(?>[^][]+|(?<o>'[)|(?<-o>]))*(?(o)(?!))])?))*

请参阅regex演示