需要复杂的Regex Split模式

时间:2013-09-07 01:24:42

标签: c# .net regex tokenize lexer

我想分割以下字符串

// Comments
KeyA : SomeType { SubKey : SubValue } KeyB:'This\'s a string'
KeyC : [ 1 2 3 ] // array value

KeyA
:
SomeType
{ SubKey : SubValue }
KeyB
:
This's a string
KeyC
:
[ 1 2 3 ]

(:和空格是分隔符,但是:保留在结果中;注释被忽略; {},[]或''之间没有分隔)

我能用Regex Split或Match实现吗?如果是这样,那么正确的模式是什么?对模式字符串的评论将不胜感激。

此外,如果输入字符串无效,也可以抛出异常或返回错误消息(参见下面的注释)。

感谢。

3 个答案:

答案 0 :(得分:1)

您可以使用此模式...

string pattern = @"(\w+)\s*:\s*((?>[^\w\s\"'{[:]+|\w+\b(?!\s*:)|\s(?!\w+\s*:|$)|\[[^]]*]|{[^}]*}|\"(?>[^\"\\]|\\.)*\"|'(?>[^'\\]|\\.)*')+)\s*";

......有两种方式:

  1. 使用匹配方法,可以使用第1组中的键和第2组中的值
  2. 为您提供所需的内容
  3. 使用Split方法,但您必须删除所有空结果。
  4. 如何构建模式的第二部分(:之后)?

    这个想法首先要避免有问题的人物:[^\w\s\"'{[:]+ 然后在特定情况下允许每个字符:

    • \w+\b(?!\s*:)一个不是关键词
    • \s(?!\w+\s*:|$)空格不在值的末尾(修剪它们)
    • \[[^]]*]内容括号括起来的内容
    • {[^}]*}与大括号相同
    • 双引号之间的
    • "(?>[^"\\]|\\\\|\\.)*"内容(允许使用转义双引号)
    • '(?>[^'\\]|\\\\|\\.)*'与单引号相同

    请注意,避免使用括号或引号内的冒号问题。

答案 1 :(得分:0)

当你到达KeyC时,我不太清楚你在寻找什么。你怎么知道KeyB的字符串值何时结束,KeyC的字符串何时开始?在'this'是字符串'或换行符之后是否有冒号?这是一个让您入门的示例:

[TestMethod]
public void SplitString()
{
    string splitMe = "KeyA : SubComponent { SubKey : SubValue } KeyB:This's is a string";
    string pattern = "^(.*):(.*)({.*})(.*):(.*)";

    Match match = Regex.Match(splitMe, pattern);

    Assert.IsTrue(match.Success);
    Assert.AreEqual(6, match.Groups.Count); // 1st group is the entire match
    Assert.AreEqual("KeyA", match.Groups[1].Value.Trim());
    Assert.AreEqual("SubComponent", match.Groups[2].Value.Trim());
    Assert.AreEqual("{ SubKey : SubValue }", match.Groups[3].Value.Trim());
    Assert.AreEqual("KeyB", match.Groups[4].Value.Trim());
    Assert.AreEqual("This's is a string", match.Groups[5].Value.Trim());
}

答案 2 :(得分:0)

这个正则表达式模式应该适合你

\s*:\s*(?![^\[]*\])(?![^{]*})(?=(([^"]*"[^"]*){2})*$|[^"]+$)

替换为

\n$0\n

Demo