问题

如何将string"Thequickbrownfoxjumps"拆分为Java中相等大小的子串。 Eg."Thequickbrownfoxjumps"的4个相同大小应该给出输出。

["Theq","uick","brow","nfox","jump","s"]

#1 热门回答(182 赞)

这是正则表达式的单行版本:

System.out.println(Arrays.toString(
"Thequickbrownfoxjumps".split("(?<=\\G.{4})")
));

\G是一个零宽度断言,匹配上一个匹配结束的位置。如果之前没有匹配,则它与输入的开头匹配,相同为132867023。封闭的lookbehind匹配从最后一个匹配结束开始的四个字符的位置。

lookbehind和\G都是高级正则表达式功能,并不是所有版本都支持。此外,\G并未在支持它的各种风格中实现一致。这个技巧将适用于(例如)Java,Perl,.NET和JGSoft,但不适用于PHP(PCRE),Ruby 1.9或TextMate(均为Oniguruma)。 JavaScript的/y(粘性标记)不像\G那样灵活,即使JS确实支持lookbehind,也不能以这种方式使用。

我应该提一下,如果你有其他选择,我不一定会推荐这个解决方案。其他答案中的非正则表达式解决方案可能更长,但它们也是自我记录的;这个只是关于那个的对立面。 ;)

此外,这在Android中不起作用,Android不支持使用\G在lookbehinds。

#2 热门回答(108 赞)

好吧,通过暴力来做这件事很容易:

public static List splitEqually(String text, int size) {
// Give the list the right capacity to start with. You could use an array
// instead if you wanted.
List ret = new ArrayList((text.length() + size - 1) / size);
for (int start = 0; start < text.length(); start += size) {
ret.add(text.substring(start, Math.min(text.length(), start + size)));
}
return ret;
}

我认为使用正则表达式并不值得。

编辑:我不使用正则表达式的理由:

这不使用正则表达式的任何实际模式匹配。这只是数数。

我怀疑上述内容会更有效率,尽管在大多数情况下无关紧要

如果你需要在不同的地方使用变量大小,你可能需要重复或辅助函数来根据参数构建正则表达式 - ick。

另一个答案中提供的正则表达式首先没有编译(无效转义),然后没有工作。我的代码第一次工作。这更像是对正则表达式与普通代码IMO的可用性的证明。

#3 热门回答(60 赞)

for(final String token :
Splitter
.fixedLength(4)
.split("Thequickbrownfoxjumps")){
System.out.println(token);
}

输出:

Theq
uick
brow
nfox
jump
s

或者,如果你需要将结果作为数组,则可以使用以下代码:

String[] tokens =
Iterables.toArray(
Splitter
.fixedLength(4)
.split("Thequickbrownfoxjumps"),
String.class
);

参考:

Splitter.fixedLength()
Splitter.split()
Iterables.toArray()

注意:拆分器结构如上所示,但由于拆分器是不可变的并且可重用,因此将它们存储在常量中是一种很好的做法:

private static final Splitter FOUR_LETTERS = Splitter.fixedLength(4);
// more code
for(final String token : FOUR_LETTERS.split("Thequickbrownfoxjumps")){
System.out.println(token);
}