如何从C#中的“StrA(StrC,StrD)(StrE)StrF”中提取“StrB(StrC,StrD)(StrE)”?

时间:2013-02-06 15:59:17

标签: c# regex string

我尝试使用这个:Regex.Match(input, @"\(([^)]*)\)"),但这会给我“(StrB(StrC,StrD)”这不是我想要的。

我想在两个括号之间提取字符串,但是里面的字符串可以有自己的一组括号,这些括号嵌套在主要的2个括号中,字符串可以用括号无限嵌套,如:

"a(b(c(d(...))))",知道怎么做的吗? 谢谢。

2 个答案:

答案 0 :(得分:4)

这将得到你想要的:

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 :(得分:0)

作为另一个选项,您可以遍历字符串,并使用括号计数器:“(”增加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;
        }
    }
}