2

次のような特別な表記法で、型名のジェネリック引数 (ジェネリックにすることもできます) をキャプチャする正規表現を記述する必要があります。

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)(?!)
)$
4

1 に答える 1

2

を使用してこれらの値をキャプチャすることをお勧めします

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

正規表現のデモを参照してください。

詳細:

  • \w+(?:\.\w+)*.- 1 回以上の + 1+単語文字が続く 1+ 単語文字に一致
  • \[- リテラル[
  • (?:,?(?<res>\w+(?:\[[^][]*])?))*- 0 個以上のシーケンス:
    • ,?- オプションのカンマ
    • (?<res>\w+(?:\[[^][]*])?)- グループ "res" キャプチャ:
      • \w+- 1 つまたは複数の単語の文字 (おそらく、希望するもの[\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);

UPDATE : 不明な深さの[...]部分文字列を考慮するには、使用します

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

正規表現のデモを見る

于 2016-08-02T12:55:05.543 に答える