问题
如何将string"Thequickbrownfoxjumps"
拆分为Java中相等大小的子串。 Eg."Thequickbrownfoxjumps"
的4个相同大小应该给出输出。
["Theq","uick","brow","nfox","jump","s"]
类似的问题:Split string into equal-length substrings in Scala
#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<String> splitEqually(String text, int size) {
// Give the list the right capacity to start with. You could use an array
// instead if you wanted.
List<String> ret = new ArrayList<String>((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 赞)
这很容易用Google Guava:
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);
}