Java使用负前瞻将字符串拆分为字符

时间:2013-10-21 19:42:00

标签: java regex string split

我试图将字符串拆分为字符串数组,问题是.split()也返回一个空元素。 ("test").split会返回["","t","e","s","t"]

此问题中的解决方案Split string into array of character strings解决了问题(使用.split("(?!^)"))。

但是我仍然无法理解为什么会这样,并且我不会使用一段我无法理解的代码,因为它完成了工作。

我已经阅读了关于负面预测的这两页http://www.regular-expressions.info/lookaround.htmlhttp://ocpsoft.org/opensource/guide-to-regular-expressions-in-java-part-2/,但仍然无法理解。有人可以澄清一下吗?

3 个答案:

答案 0 :(得分:5)

使用("test").split()会将字符串拆分到字符前的每个位置,从而产生["", "t", "e", "s", "t"],因为第一次拆分(在t之前)将导致空条目。

此正则表达式("(?!^)")的意思是:在每个字符处拆分字符串,其中不是行开头(^)是前一个字符 *:

你的字符串基本上看起来(对于Regex引擎)是这样的:^test$ 因此,正则表达式将执行每个拆分,除了在第一个t之前的拆分,因为它匹配^ - 当当前位置前面的字符为{时,它不应该拆分{1}}(String / Line-Start)。

* actualley ^不是一个字符,这就是为什么你在^之前没有另一个分裂 - 它们只是元字符 - 所以说。

答案 1 :(得分:2)

您需要先了解返回数组包含空第一个元素的原因。当您在索引0处出现的分隔符上拆分字符串时,它也会在该分隔符上拆分。现在分隔符的左侧是一个空字符串,它是存储在数组索引0的内容。

因此,以下代码将第一个数组元素作为空字符串:

"#ab#c".split("#");  // ["", "ab", "c"]

但是,如果#不是字符串的第一个字符,则不会在索引0处获得空字符串。

现在,如果您不希望将空字符串作为第一个元素,则只需要避免在第一个#上拆分。你会怎么做?通过使用否定的后视,确保您分组的#不在字符串的开头 - ^

"#ab#c".split("(?<!^)#");  // ["ab", "c"]

#前面没有字符串(?<!^)的开头时,此正则表达式会分开。 ^表示字符串的开头,(?<!...)表示负面的后视。


所以,现在你的分隔符本身就是一个空字符串。请记住,字符串在每个字符前面都包含一个空字符串,在最后一个字符之后也是如此。因此,简单地拆分空字符串,将拆分在第一个字符之前的分隔符上。你需要拆分空字符串,除了开头的字符串。用空字符串替换#

"abc".split("(?<!^)");  // ["a", "b", "c"]

同样,负面前瞻工作 - (?!^),但IMO,负面观察在这里更直观。


当然,如果您只想将字符串分解为字符数组,则可以使用String#toCharArray()方法。

答案 2 :(得分:1)

嗯,可能我不明白你的问题,但为什么不使用toCharArray()方法呢?