私はこれを使おうとしました:Regex.Match(input, @"\(([^)]*)\)")
、しかしこれは私に「(StrB(StrC、StrD)」を与えます、それは私が望むものではありません。
2つの括弧の間に文字列を抽出したいのですが、中にある文字列は、メインの2つの括弧の中にネストされた独自の括弧のセットを持つことができ、文字列は次のような括弧で無限にネストできます。
"a(b(c(d(...))))"
、これがどのように行われるかについて何か考えはありますか?ありがとう。
これはあなたが望むものを手に入れるでしょう:
var regex = new Regex(
@"(?<=\()(?:[^()]|(?<br>\()|(?<-br>\)))*(?(br)(?!))(?=\))");
var input = "StrA(StrB(StrC,StrD)(StrE)) StrF";
var matches = regex.Matches(input);
正規表現は次のように分類されます。
(?<=\() Preceeded by a (
(?: Don't bother capturing a group
[^()]+ Match one or more non-brackets
| OR
(?<br>\() Capture a (, increment the br count
| OR
(?<-br>\)) Capture a ), decrement the br count or fail if it's 0
(failing here will mean we've reached the end of our match)
)
* Zero or more times
(?(br)(?!)) Fail if there's the br count is greater than zero
(Literally, if it's greater than zero, match a (?!);
(?!) means 'not followed by ""', which always fails)
(?=\)) Succeeded by a )
別のオプションとして、文字列を反復処理し、括弧にカウンターを使用できます。「」の場合は1ずつ増やし、「(
」の場合は減らし)
ます。カウンターがゼロになるか、文字列の終わりに達したときに停止します。
var str = "StrA(StrB(StrC,StrD)(StrE)) StrF";
string result = null;
int count = 0;
var firstIndex = str.IndexOf('(');
if (firstIndex != -1)
{
count++;
for (int i = firstIndex + 1; i < str.Length; i++)
{
switch (str[i])
{
case '(':
count++;
break;
case ')':
count--;
break;
}
if (count == 0)
{
result = str.Substring(firstIndex + 1, i - firstIndex - 1);
break;
}
}
}