正则表达式嵌套括号
本文关键字:嵌套 正则表达式 | 更新日期: 2023-09-27 18:36:57
>我有以下字符串:
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
目标是将括号中具有相同索引的部分嵌套以操纵未来。
谢谢。
编辑
正在尝试改进示例...
想象一下我有这个字符串
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))
我希望我已经解释得更好一点,对不起。
你可以使用这个:
(?>'w+'.)?'w+'((?>'((?<DEPTH>)|')(?<-DEPTH>)|[^()]+)*')(?(DEPTH)(?!))|'w+
通过您的示例,您可以获得:
0 => username
1 => TB_PEOPLE.fields(FirstName,LastName,TB_PHONE.fields(num_phone1, num_phone2))
2 => password
解释:
(?>'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)
您可以使用以下代码尝试:
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);
}
我建议一个新的策略,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)
(字符串复制除外,这是最糟糕的部分):
depth = parenthetical_depth(bit)
while depth != 0:
nbit = fetch next from bits
depth = depth + parenthetical_depth(nbit)
bit = bit + ',' + nbit
通过巧妙地使用缓冲区和缓冲区大小,可以提高字符串复制的效率,但代价是空间效率,但我认为 C# 本身无法为您提供这种级别的控制。
如果我正确理解了您的示例,那么您正在寻找这样的东西:
(?<head>[a-zA-Z._]+',)*(?<body>[a-zA-Z._]+[(].*[)])(?<tail>.*)
对于给定的字符串:
用户名,TB_PEOPLE.字段(名字,姓氏,TB_PHONE.字段(num_phone1,num_phone2)),密码
此表达式将匹配
- 用户名,用于组长
- TB_PEOPLE.组正文的字段(名字,姓氏,TB_PHONE.字段(num_phone1,num_phone2))
- ,组尾的密码