0

我想拆分以下字符串

// 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 ]

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

我可以通过正则表达式拆分或匹配来实现吗?如果是这样,正确的模式是什么?对模式字符串的评论将不胜感激。

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

谢谢。

4

3 回答 3

1

你可以使用这个模式...

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

...有两种方式:

  1. 使用 Match 方法,它将为您提供您正在寻找的内容,其中包含第 1 组中的键和第 2 组中的值
  2. 使用 Split 方法,但您必须删除所有空结果。

如何构建:模式的第二部分(在 之后)?

这个想法是首先避免有问题的字符:[^\w\s\"'{[:]+ 然后您允许这些字符中的每一个,但在特定情况下:

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

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

于 2013-09-07T02:03:37.033 回答
0

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

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

当替换为

\n$0\n

演示

于 2013-09-07T04:53:26.757 回答
0

当您到达 KeyC 时,我不太确定您在寻找什么。您如何知道 KeyB 的字符串值何时结束而 KeyC 的字符串何时开始?'this\'s is a string' 或换行符后是否有冒号?这是一个让您入门的示例:

[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());
}
于 2013-09-07T01:47:56.493 回答