c# - 在 C# 中使用正则表达式拆分字符串

标签 c# regex string split

我需要从另一个系统中拆分一个字符串,它代表一个序列化的对象。对象本身可以有另一个相同类型的对象作为属性嵌套。我需要一种方法来将字符串本质上序列化为字符串数组。例如。

"{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

ideone demo


简要说明:

(?=[^{}]*(?:(?:(?'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/

相关文章:

c# - 使用自定义值更新

c# - 子进程和父进程之间共享值

regex - 将数字与 R 中的文本分开

java - 将 byte[] 转换为 Java 字符串。添加一个?在每次转换中

c++ - string& 和 char* 版本的 string::append()、string::replace() 和 string::compare()

c# - 使用 LINQ 将对象属性合并到列表中

javascript - Node.js semver 中的正则表达式非捕获组

javascript - 正则表达式验证三位数和一位小数

java - 使用 LRU 缓存时避免字符串分配

c# - Entity Framework - "An error occurred while updating the entries. See the inner exception for details"