正则表达式用逗号分隔,但不在任何括号内,并考虑了递归

时间:2016-02-01 13:21:43

标签: c# regex

我有一个示例字符串:

string myString = "value,value,(value,(value, value, value, (value), value),value)";

目标是迭代它并将其反序列化为类对象的层次结构。

大多数其他在这里提出类似问题的例子不起作用的原因是由于递归,因为偶数个括号不能正常工作。(/ p>

我考虑将其存储为JSON,但是值的对象类型会在没有通知的情况下发生变化,并且在过去已证明甚至混淆了json.net,特别是因为类型可能都是通过继承来关联的。

因此,给定示例字符串,目标是在逗号“,”上拆分,但忽略括号中的所有内容,直到我的递归循环挖掘到该子集,然后使用相同的正则表达式来拆分其内容。

我还没有代码,因为我仍在集思广益这个方法。

另请注意,子列表可能不一定是父列表中的最后一个元素,最后在我的示例中有几个挥之不去的value所示。

如果没有完整阅读问题并理解为何与this

等问题不同,请不要标记为重复

1 个答案:

答案 0 :(得分:2)

虽然C#正则表达式具有允许您匹配递归括号组的功能(请参阅this Q&A for an example),但为正面情况定义此类正则表达式要容易得多(即"匹配单词或整个括号内容) group")与分裂所需的否定案例(即"匹配逗号,除非它在括号内的组")。

此外,在您希望递归应用相同的正则表达式的情况下,构建简单的Recursive Descent Parser有一个优势。

解析器的核心是分割逻辑,它在搜索逗号时计算括号,并在括号级别为零时分割:

var parts = new List<string>();
var parenLevel = 0;
var lastPos = 0;
for (var i = 0 ; i != s.Length ; i++) {
    switch (s[i]) {
        case '(':
            parenLevel++;
            break;
        case ')':
            parenLevel--;
            if (parenLevel < 0) {
                throw new ArgumentException();
            }
            break;
        case ',':
            if (parenLevel == 0) {
                parts.Add(s.Substring(lastPos, i-lastPos));
                lastPos = i + 1;
            }
            break;
    }
}
if (lastPos != s.Length) {
    parts.Add(s.Substring(lastPos, s.Length - lastPos));
}

Demo.