TL;DR: これはオプションのソリューションです
var str = @"You have {notifications, plural,
zero {no notifications}
one {one notification}
=42 {a universal amount of notifications}
other {# notifications}
}. Have a nice day, {name}!";
// get matches skipping nested curly braces
var matches =
Regex.Matches(str, @"{((?:[^{}]|(?<counter>{)|(?<-counter>}))+(?(counter)(?!)))}");
var results = matches.Cast<Match>().Select(m => m.Groups[1].Value).Distinct()
.Select(v => Regex.Match(v, @"^\w+").Value) // take 1st word
.ToList();
その結果(デバッグ中にVisual Studioローカルウィンドウからコピー)
results Count = 2 System.Collections.Generic.List<string>
[0] "notifications"
[1] "name"
...元の答えは続きます...
元の質問の現在の解決策について注意すべき点が 1 つあります。
- の使用は
.
改行と一致しないため、現在ネストされた値と一致する理由の 1 つです (このソースを参照)
あなたの目標を理解できれば、この記事は関連する問題と解決策の素晴らしい説明とデモンストレーションです。
(この記事では、元の質問で指摘された主な課題、つまりネストされた中括弧について説明します)
https://blogs.msdn.microsoft.com/timart/2013/05/14/nestedrecursive-regex-and-net-balancing-groups-detect-a-function-with-a-regex/
その記事から、オプションの解決策として以下のパターンを提案します。
var str = @"You have {notifications, plural,
zero {no notifications}
one {one notification}
=42 {a universal amount of notifications}
other {# notifications}
}. Have a nice day, {name}!";
// get matches skipping nested curly braces
var matches =
Regex.Matches(str, @"{((?:[^{}]|(?<counter>{)|(?<-counter>}))+(?(counter)(?!)))}");
var results = matches.Cast<Match>().Select(m => m.Groups[1].Value).Distinct().ToList();
その結果(デバッグ中にVisual Studioローカルウィンドウからコピー)
results Count = 2 System.Collections.Generic.List<string>
[0] "notifications, plural,\r\n zero {no notifications}\r\n one {one notification}\r\n =42 {a universal amount of notifications}\r\n other {# notifications}\r\n "
[1] "name"
(または、これらの結果をコンソールに出力する場合):
// Result 0 would look like:
notifications, plural,
zero {no notifications}
one {one notification}
=42 {a universal amount of notifications}
other {# notifications}
// Result 1 would look like:
name
アップデート
私はこれに戻って、質問が結果として単語を 1 つだけ要求していることに気付きました。
次に、各結果から最初の単語を取得します
(完全な解決策を示すために、追加の select ステートメントを使用して上記のスニペットを繰り返しています)
var str = @"You have {notifications, plural,
zero {no notifications}
one {one notification}
=42 {a universal amount of notifications}
other {# notifications}
}. Have a nice day, {name}!";
// get matches skipping nested curly braces
var matches =
Regex.Matches(str, @"{((?:[^{}]|(?<counter>{)|(?<-counter>}))+(?(counter)(?!)))}");
var results = matches.Cast<Match>().Select(m => m.Groups[1].Value).Distinct()
.Select(v => Regex.Match(v, @"^\w+").Value) // take 1st word
.ToList();
その結果(デバッグ中にVisual Studioローカルウィンドウからコピー)
results Count = 2 System.Collections.Generic.List<string>
[0] "notifications"
[1] "name"
もう少し情報
(私はこれが興味深いと感じ、調査/学習にもう少し時間を費やし、さらに関連情報を含める価値があると考えました)
こことここでの会話には、この種の問題に正規表現を使用することに賛成または反対する意見が含まれています。
- これらの意見を読んで、よりバランスの取れた視点を得ることは興味深いと思います
上記の意見に関係なく、.NET の作成者は、バランス グループ定義を実装することが適切であると考えました。これは、この回答が使用する機能です。