我需要从另一个系统中拆分一个字符串,它代表一个序列化的对象。对象本身可以有另一个相同类型的对象作为属性嵌套。我需要一种方法来将字符串本质上序列化为字符串数组。例如。
"{1,Dave,2}"
应该创建一个包含 3 个元素的字符串数组 "1", "Dave", "2"
。
"{1,{Cat,Yellow},2}"
应该变成一个包含 3 个元素的数组 "1", "{Cat,Yellow}", "2"
.
"{1,{Cat,{Blue,1}},2}"
应该变成一个包含 3 个元素的数组 "1", "{Cat,{Blue,1} }", "2"
.
基本上嵌套可以是 N 级深,所以我可能有类似的东西 “{{Cat,{Blue,1}},{Dog,White}}”和我生成的数组应该有 2 个元素:“{Cat,{Blue,1}}”和“{Dog,White}”
我想写一个自定义解析器来手动解析字符串。但这似乎是 RegEx 旨在解决的问题,但是,我对 regex 不是很擅长,因此非常感谢 RegEx 专家的一些指导。
谢谢
最佳答案
那么,您可以使用利用 balancing groups 的拆分:
,(?=[^{}]*(?:(?:(?'O'{)[^{}]*)+(?:(?'-O'})[^{}]*?)+)*(?(O)(?!))$)
它将匹配前面没有 {}
的逗号或 {}
中的组。
在代码中:
string msg= "{1,{Cat,{Blue,1}},2}";
msg = msg.Substring(1, msg.Length - 2);
string[] charSetOccurences = Regex.Split(msg, @",(?=[^{}]*(?:(?:(?'O'{)[^{}]*)+(?:(?'-O'})[^{}]*?)+)*(?(O)(?!))$)");
foreach (string s in charSetOccurences)
{
Console.WriteLine(s);
}
输出:
1
{Cat,{Blue,1}}
2
简要说明:
(?=[^{}]*(?:(?:(?'O'{)[^{}]*)+(?:(?'-O'})[^{}]*?)+)*(?(O)(?!))$)
是一个巨大的前瞻......
[^{}]*
将匹配除 {}
之外的任何字符任意次数。
(?:(?:(?'O'{)[^{}]*)+(?:(?'-O'})[^{}]*?)+)*( ?(O)(?!))
将匹配具有任何嵌套级别的 {}
组。
它首先会捕获一个开头的 {
并将其命名为 O
(我选择它的意思是“开头”):
(?:(?:(?'O'{)[^{}]*)+(?:(?'-O'})[^{}]*?)+)*(?(O)(?!))
^
然后是除大括号之外的任何字符:
(?:(?:(?'O'{)[^{}]*)+(?:(?'-O'})[^{}]*?)+)*(?(O)(?!))
^^^^^^
并重复该组以适应嵌套:
(?:(?:(?'O'{)[^{}]*)+(?:(?'-O'})[^{}]*?)+)*(?(O)(?!))
^
这部分平衡左大括号:
(?:(?:(?'O'{)[^{}]*)+(?:(?'-O'})[^{}]*?)+)*(?(O)(?!))
^^^^^^^^
与其他非 {}
一起重复以适应嵌套:
(?:(?:(?'O'{)[^{}]*)+(?:(?'-O'})[^{}]*?)+)*(?(O)(?!))
^^^^^^^ ^
所有这一切,至少 0 次:
(?:(?:(?'O'{)[^{}]*)+(?:(?'-O'})[^{}]*?)+)*(?(O)(?!))
^
最后一个条件否定前瞻只是一个闭包,并确保没有不平衡的括号。
关于c# - 在 C# 中使用正则表达式拆分字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21156414/