Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 正则表达式嵌套括号_C#_.net_Regex_String - Fatal编程技术网

C# 正则表达式嵌套括号

C# 正则表达式嵌套括号,c#,.net,regex,string,C#,.net,Regex,String,我有以下字符串: a,b,c,d.e(f,g,h,i(j,k)),l,m,n 您知道如何构建一个只返回“第一级”括号的正则表达式吗 [0] = a,b,c, [1] = d.e(f,g,h,i.j(k,l)) [2] = m,n (?<head>[a-zA-Z._]+\,)*(?<body>[a-zA-Z._]+[(].*[)])(?<tail>.*) 目标是保持括号中具有相同索引的部分嵌套,以便将来操作 多谢各位 编辑 尝试改进示例 想象一下我有这根绳

我有以下字符串:

a,b,c,d.e(f,g,h,i(j,k)),l,m,n
您知道如何构建一个只返回“第一级”括号的正则表达式吗

[0] = a,b,c,
[1] = d.e(f,g,h,i.j(k,l))
[2] = m,n
(?<head>[a-zA-Z._]+\,)*(?<body>[a-zA-Z._]+[(].*[)])(?<tail>.*)
目标是保持括号中具有相同索引的部分嵌套,以便将来操作

多谢各位

编辑

尝试改进示例

想象一下我有这根绳子

username,TB_PEOPLE.fields(FirstName,LastName,TB_PHONE.fields(num_phone1, num_phone2)),password
我的目标是将字符串转换为动态查询。 然后,不以“TB_”开头的字段我知道它们是主表的字段,否则我知道括号内的informandos字段与另一个表相关。 但是我很难检索所有“第一级”字段,因为我可以将它们从相关表中分离出来,我可以递归地恢复其余字段

最后,会有类似于:

[0] = username,password
[1] = TB_PEOPLE.fields(FirstName,LastName,TB_PHONE.fields(num_phone1, num_phone2))

我希望我解释得更清楚一点,对不起。

如果我正确理解了您的示例,您正在寻找以下内容:

[0] = a,b,c,
[1] = d.e(f,g,h,i.j(k,l))
[2] = m,n
(?<head>[a-zA-Z._]+\,)*(?<body>[a-zA-Z._]+[(].*[)])(?<tail>.*)
(?[a-zA-Z.\+\,)*(?[a-zA-Z.\+[(].[]))(?*)
对于给定字符串:

用户名、TB_PEOPLE.fields(名字、姓氏、TB_PHONE.fields(num_phone1、num_phone2))、密码

此表达式将匹配

  • 用户名,用于组
  • TB\u人.字段(名字、姓氏、TB\u电话.字段(num\u phone1、num\u phone2))用于组body
  • ,组尾部的密码

我建议一种新的策略,R2——用算法实现。虽然您可以构建一个最终将接近您要求的正则表达式,但它将无法维护,并且当您发现新的边缘情况时很难扩展。我不会说C#,但这段伪代码应该会让您走上正确的轨道:

function parenthetical_depth(some_string):
    open = count '(' in some_string
    close = count ')' in some_string
    return open - close

function smart_split(some_string):
    bits = split some_string on ','
    new_bits = empty list
    bit = empty string
    while bits has next:
        bit = fetch next from bits
        while parenthetical_depth(bit) != 0:
            bit = bit + ',' + fetch next from bits
        place bit into new_bits
    return new_bits
这是最容易理解的方法,目前的算法是
O(n^2)
-对内部循环进行了优化,使其
O(n)
(字符串复制除外,这是其中最糟糕的部分):

通过巧妙地使用缓冲区和缓冲区大小,可以提高字符串复制的效率,但我认为C#无法在本地为您提供这种级别的控制。

您可以使用以下方法:

(?>\w+\.)?\w+\((?>\((?<DEPTH>)|\)(?<-DEPTH>)|[^()]+)*\)(?(DEPTH)(?!))|\w+
说明:

(?>\w+\.)? \w+ \(    # the opening parenthesis (with the function name)
(?>                  # open an atomic group
    \(  (?<DEPTH>)   # when an opening parenthesis is encountered,
                     #  then increment the stack named DEPTH
  |                  # OR
    \) (?<-DEPTH>)   # when a closing parenthesis is encountered,
                     #  then decrement the stack named DEPTH
  |                  # OR
    [^()]+           # content that is not parenthesis
)*                   # close the atomic group, repeat zero or more times
\)                   # the closing parenthesis
(?(DEPTH)(?!))       # conditional: if the stack named DEPTH is not empty
                     #  then fail (ie: parenthesis are not balanced)
(?>\w+\)\w+\(#左括号(带函数名)
(?>#打开一个原子群
\(?)#当遇到左括号时,
#然后增加名为DEPTH的堆栈
|#或
\)(?)#遇到右括号时,
#然后递减名为DEPTH的堆栈
|#或
[^()]+#不是括号的内容
)*#关闭原子组,重复零次或多次
\)#右括号
(?(深度)(?!)#条件:如果名为DEPTH的堆栈不为空
#然后失败(即:括号不平衡)
您可以使用以下代码进行尝试:

string input = "username,TB_PEOPLE.fields(FirstName,LastName,TB_PHONE.fields(num_phone1, num_phone2)),password";
string pattern = @"(?>\w+\.)?\w+\((?>\((?<DEPTH>)|\)(?<-DEPTH>)|[^()]+)*\)(?(DEPTH)(?!))|\w+";
MatchCollection matches = Regex.Matches(input, pattern);
foreach (Match match in matches)
{
    Console.WriteLine(match.Groups[0].Value);
}
string input=“用户名,TB_人.字段(名字,姓氏,TB_电话.字段(num_电话1,num_电话2)),密码”;
字符串模式=@“(?>\w+\)?\w+\(?>\((?)|\)(?)|[^()]+)*\(?(深度)(?!)|\w+”;
MatchCollection matches=Regex.matches(输入,模式);
foreach(匹配中的匹配)
{
Console.WriteLine(match.Groups[0].Value);
}

我不明白你的例子。不应该匹配
[1]
(f,g,h,I.j(k,l))
?如果没有,你能再解释一下吗?据我所知,正则表达式无法解析嵌套结构示例输入和输出没有意义。一个是
(j,k)
,另一个是
(k,l)
@casimirithippolyte:source或proof it…嗨!我正试图完全按照您所说的那样应用正则表达式,但我得到的回报是:[0]=>“[1]=>”、“[2]=>”、“,[3]=>”。您能告诉我忘记做什么吗?谢谢。您最好在原子组中使用嵌套的量化组,以防止回溯并加快对失败匹配的识别。例如,
\((?>(?:\(?)|\)(?)|[^()]+)*)\
。但是,如果您不关心故障性能,那么就没有必要这样做。(此处的空格仅用于可读性)