使用String.split()提取单词对
鉴于:
String input = "one two three four five six seven";
是否有一个正则expression式可以与String.split()
一起抓取(最多)两个单词,例如:
String[] pairs = input.split("some regex"); System.out.println(Arrays.toString(pairs));
结果如下:
[one two, three four, five six, seven]
这个问题是关于分裂正则expression式 。 这不是 “寻找解决办法”或其他“以另一种方式工作”的解决scheme。
目前(包括Java 8)可以使用split()
,但在现实世界中不要使用这种方法,因为它看起来像是基于bug(Java中的后台应该有明显的最大长度,但是这个解决scheme使用\w+
不尊重这个限制)。 相反,使用Pattern
和Matcher
类来避免过度繁杂和维护地狱,因为这种行为可能在Java的下一个版本或像Java这样的Java环境中发生变化。
这是你想要的?
(你可以用\\S
replace\\w
以包含所有非空格字符,但是对于这个例子我将离开\\w
因为用\\w\\s
来读取正则expression式更容易\\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
我们正在尝试
- find空格 – >
\\s
- 没有预测 – >
(?<!negativeLookBehind)
- 通过一些单词 – >
\\w+
- 与先前匹配(空间) – >
\\G
- 在它之前 – >
\\G\\w+
。
只有我一开始就感到困惑,因为我们希望这个空间被忽略,它对于第一空间将会如何工作。 重要的信息是\\G
在开始比赛开始string^
。
所以在第一次迭代之前,负面后视中的正则expression式看起来像(?<!^\\w+)
并且由于第一个空间之前有^\\w+
,所以它不能匹配分割。 下一个空间不会有这个问题,所以它会被匹配,并且关于它的信息(比如它在input
string中的位置 )将被存储在\\G
并在以后的负面后续处理中使用。
因此,对于第三空间,正则expression式将检查之前是否有先前匹配的空间\\G
和word \\w+
。 由于这个testing的结果是肯定的,所以负面的后视不会接受它,所以这个空间不会被匹配,但是第四空间不会有这个问题,因为它之前的空间不会像存储在\\G
(它将有不同的位置在input
string)。
此外,如果有人想分开让我们说每隔三个空间,你可以使用这种forms(基于@maybeWeCouldStealAVan的答案 ,当我发布这个答案的片段时被删除)
input.split("(?<=\\G\\w{1,100}\\s\\w{1,100}\\s\\w{1,100})\\s")
而不是100,你可以使用一些更大的值,至less是String中最长单词的长度。
我只是注意到,如果我们想要每隔{1,maxWordLength}
每一个奇数分割,我们也可以使用+
而不是{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
这将工作,但最大字长需要提前设置:
String input = "one two three four five six seven eight nine ten eleven"; String[] pairs = input.split("(?<=\\G\\S{1,30}\\s\\S{1,30})\\s"); System.out.println(Arrays.toString(pairs));
我更喜欢Pshemo的答案,在任意词长度上更短,更易于使用,但是(如@Pshemo所指出的)具有适用于2个以上单词组的优点。
这工作对我来说(\w+\s*){2}\K\s
这里 (\w+\s*){2}\K\s
例子
- 一个必需的单词后跟一个可选的空格
(\w+\s*)
- 重复两次
{2}
- 忽略以前匹配的字符
\K
- 所需空间
\s
你可以试试这个:
[az]+\s[az]+
更新:
([az]+\s[az]+)|[az]+
更新:
String pattern = "([az]+\\s[az]+)|[az]+"; String input = "one two three four five six seven"; Pattern splitter = Pattern.compile(pattern); String[] results = splitter.split(input); for (String pair : results) { System.out.println("Output = \"" + pair + "\"");