目前(最后在 Java 14 上测试)可以用 来做split()
,但在现实世界中不要使用这种方法,因为它看起来像是基于错误,因为 Java 中的后视应该有明显的最大长度,但是这个解决方案\w+
不遵守此限制并且以某种方式仍然有效的用途- 因此,如果它是一个将在以后的版本中修复的错误,则此解决方案将停止工作。
取而代之的是使用Pattern
和Matcher
带有正则表达式的类\w+\s+\w+
,除了更安全之外,还可以避免继承此类代码的人的维护地狱(请记住“始终编写代码,就好像最终维护您的代码的人是一个知道您住在哪里的暴力精神病患者”) .
这是你想要的?
(您可以替换\\w
为\\S
以包含所有非空格字符,但对于此示例,我将离开,因为使用then\\w
更容易阅读正则表达式)\\w\\s
\\S\\s
String input = "one two three four five six seven";
String[] pairs = input.split("(?<!\\G\\w+)\\s");
System.out.println(Arrays.toString(pairs));
输出:
[one two, three four, five six, seven]
\G
是前一场比赛,(?<!regex)
是消极的向后看。
在split
我们试图
- 查找空格->
\\s
- 未预测的->
(?<!negativeLookBehind)
- 一句话——>
\\w+
- 与先前匹配的(空格)->
\\G
- 在它之前 ->
\\G\\w+
。
我一开始唯一的困惑是它如何用于第一个空格,因为我们希望忽略那个空格。重要信息是\\G
at start 匹配 String 的开头^
。
因此,在第一次迭代正则表达式之前,负后视会看起来像(?<!^\\w+)
,并且由于第一个空间之前确实有^\\w+
,它不能匹配拆分。下一个空间不会有这个问题,所以它会被匹配并且关于它的信息(比如它在字符串中的位置input
)将被存储\\G
并在以后的下一个否定后视中使用。
因此,对于第三个空格,正则表达式将检查之前是否有先前匹配的空格\\G
和单词\\w+
。由于这个测试的结果是肯定的,否定的后视不会接受它,所以这个空间不会被匹配,但是第 4 个空间不会有这个问题,因为它之前的空间不会与存储的相同\\G
(它将在input
字符串中具有不同的位置) .
另外,如果有人想分开让我们说每个第三个空格,您可以使用此表格(基于@maybeWeCouldStealAVan的答案,当我发布此答案片段时该答案已被删除)
input.split("(?<=\\G\\w{1,100}\\s\\w{1,100}\\s\\w{1,100})\\s")
您可以使用更大的值代替 100,它至少是字符串中最长单词长度的大小。
我刚刚注意到,如果我们想用每个奇数分割,例如每 3、5、7 个,我们也可以使用+
而不是{1,maxWordLength}
String data = "0,0,1,2,4,5,3,4,6,1,3,3,4,5,1,1";
String[] array = data.split("(?<=\\G\\d+,\\d+,\\d+,\\d+,\\d+),");//every 5th comma