正则表达式分割字符串但考虑多位数转义序列

时间:2010-12-14 16:54:17

标签: regex escaping

我可能需要一些关于正则表达式的以下问题的帮助,并希望得到任何帮助,在此先感谢。

我必须用另一个字符串拆分字符串,让我称之为 separator 。但是,如果转义序列在 separatorString 之前,则此时不应拆分该字符串。转义序列也是一个字符串,让我称之为 escapeSequence

也许最好从一些例子开始

separatorString = "§§";

escapeSequence = "###";

inputString = "Part1§§Part2" ==> Desired output: "Part1", "Part2"
inputString = "Part1§§Part2§§ThisIs###§§AllPart3" ==> Desired output: "Part1", "Part2", "ThisIs###§§AllPart3"

搜索stackoverflow,我找到了Splitting a string that has escape sequence using regular expression in Java并提出了正则表达式

"(?<!(###))§§"

这基本上是说,如果找到“§§”则匹配,除非它以“###”开头。

对于上面的示例,这适用于Regex.Split,但是,如果inputString为"Part1###§§§§Part2",我会收到"Part1###§", "§Part2"而不是"Part1###§§", "Part2"

我理解为什么,因为第二个“§”给出一个匹配,因为前面的字符是“##§”而不是“###”。我试了几个小时来修改正则表达式,但结果却变得更糟。有人有想法吗?

2 个答案:

答案 0 :(得分:1)

让我们调用分隔符标记之间出现的内容。你的正则表达式需要规定令牌的开头和结尾是什么样的。

在没有任何规定的情况下,换句话说,使用你现在拥有的正则表达式,正则表达式引擎很高兴地说第一个标记是Part1###§而第二个标记是§Part2

您使用的语法(?<!foo)称为零宽度负面后置断言。换句话说,它查看当前匹配的后面,并断言它必须匹配 foo 。零宽度表示在评估断言时断言不会使主题字符串中的指针或光标前进。

如果您要求新令牌以特定内容(例如,字母数字字符)开头,则可以使用零宽度正向前瞻断言指定该令牌。它类似于你的lookbehind,但它说“下一个必须匹配下面的模式”,再次没有推进光标或指针。

要使用它,请将(?=[A-Z])放在§§之后。然后,分隔符的整个正则表达式为
(?<!###)§§(?=[A-z])

这将声明分隔符序列后面的字符需要是大写字母alpha,而分隔符序列之前的字符不能是###。在您的示例中,它会强制§§分隔符上的匹配为Part2之前的一对字符。然后,您将获得Part1###§§Part2作为令牌或群组捕获。

如果你想规定一个令牌是否为负数 - 换句话说,规定一个令牌以开头,除了某个模式,你可以使用否定先行断言。其语法为(?!foo)。它可以像你期望的那样工作 - 就像你的负面观察,只是期待。

regular-expressions.info website对所有正则表达式都有很好的解释,包括for the lookahead and lookbehind constructs

ps:它是“Hello All”,而不是“Hello Together”。

答案 1 :(得分:0)

如何做相反的事情:不要在分隔符处拆分字符串,而是匹配非分隔符部分和分隔符部分:

/(?:[^§#]|§[^§#]|#(?:[^#]|#(?:[^#]|#§§)))+|§§/

然后您只需删除每个匹配的分隔符部分以获取非分隔符部分。