string按照分割 - 在Java中将字符串拆分为长度相等的子字符串
text split java (9)
如何将字符串"Thequickbrownfoxjumps"
拆分为Java中的大小相同的子字符串。 例如。 4个相同大小的"Thequickbrownfoxjumps"
应该给出输出。
["Theq","uick","brow","nfox","jump","s"]
类似问题:
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的构造如上所示,但由于Splitters是不可变的且可重用的,因此将它们存储在常量中是一种很好的做法:
private static final Splitter FOUR_LETTERS = Splitter.fixedLength(4);
// more code
for(final String token : FOUR_LETTERS.split("Thequickbrownfoxjumps")){
System.out.println(token);
}
你可以使用来自String.class
(处理异常)的substring
或来自Apache lang commons (它为你处理异常)
static String substring(String str, int start, int end)
把它放在一个循环中,你很好走。
如果您想要将字符串向后均分(即从右向左),例如将1010001111
分割为[10, 1000, 1111]
,则代码如下:
/**
* @param s the string to be split
* @param subLen length of the equal-length substrings.
* @param backwards true if the splitting is from right to left, false otherwise
* @return an array of equal-length substrings
* @throws ArithmeticException: / by zero when subLen == 0
*/
public static String[] split(String s, int subLen, boolean backwards) {
assert s != null;
int groups = s.length() % subLen == 0 ? s.length() / subLen : s.length() / subLen + 1;
String[] strs = new String[groups];
if (backwards) {
for (int i = 0; i < groups; i++) {
int beginIndex = s.length() - subLen * (i + 1);
int endIndex = beginIndex + subLen;
if (beginIndex < 0)
beginIndex = 0;
strs[groups - i - 1] = s.substring(beginIndex, endIndex);
}
} else {
for (int i = 0; i < groups; i++) {
int beginIndex = subLen * i;
int endIndex = beginIndex + subLen;
if (endIndex > s.length())
endIndex = s.length();
strs[i] = s.substring(beginIndex, endIndex);
}
}
return strs;
}
我问@Alan Moore对接受的解决方案的评论如何处理换行符。 他建议使用DOTALL。
使用他的建议,我创建了一个小样本,它是如何工作的:
public void regexDotAllExample() throws UnsupportedEncodingException {
final String input = "The\nquick\nbrown\r\nfox\rjumps";
final String regex = "(?<=\\G.{4})";
Pattern splitByLengthPattern;
String[] split;
splitByLengthPattern = Pattern.compile(regex);
split = splitByLengthPattern.split(input);
System.out.println("---- Without DOTALL ----");
for (int i = 0; i < split.length; i++) {
byte[] s = split[i].getBytes("utf-8");
System.out.println("[Idx: "+i+", length: "+s.length+"] - " + s);
}
/* Output is a single entry longer than the desired split size:
---- Without DOTALL ----
[Idx: 0, length: 26] - [[email protected]
*/
//DOTALL suggested in Alan Moores comment on SO: https://.com/a/3761521/1237974
splitByLengthPattern = Pattern.compile(regex, Pattern.DOTALL);
split = splitByLengthPattern.split(input);
System.out.println("---- With DOTALL ----");
for (int i = 0; i < split.length; i++) {
byte[] s = split[i].getBytes("utf-8");
System.out.println("[Idx: "+i+", length: "+s.length+"] - " + s);
}
/* Output is as desired 7 entries with each entry having a max length of 4:
---- With DOTALL ----
[Idx: 0, length: 4] - [[email protected]
[Idx: 1, length: 4] - [[email protected]
[Idx: 2, length: 4] - [[email protected]
[Idx: 3, length: 4] - [[email protected]
[Idx: 4, length: 4] - [[email protected]
[Idx: 5, length: 4] - [[email protected]
[Idx: 6, length: 2] - [[email protected]
*/
}
但是我也喜欢@Jon Skeets解决方案https://.com/a/3760193/1237974 。 对于大型项目中的可维护性,并非每个人在正则表达式中都有同样的经验,我可能会使用Jons解决方案。
这是正则表达式单线版本:
System.out.println(Arrays.toString(
"Thequickbrownfoxjumps".split("(?<=\\G.{4})")
));
\G
是一个零宽度断言,与上一场比赛结束的位置相匹配。 如果之前没有匹配,则匹配输入的开头,与\A
相同。 封闭倒序与最后一场比赛结束时的四个字符相匹配。
lookbehind和\G
都是高级的正则表达式功能,并不受所有风格的支持。 此外, \G
并没有贯彻支持它的口味。 这个技巧可以用于Java ,Perl,.NET和JGSoft,但不适用于PHP (PCRE),Ruby 1.9+或TextMate(都是Oniguruma)。 JavaScript的/y
(sticky flag)不如\G
那么灵活,即使JS确实支持后视,也不能这样使用。
我应该提到,如果您有其他选择,我不一定会推荐此解决方案。 其他答案中的非正则表达式解决方案可能更长,但它们也是自我记录的; 这个只是与此相反 。 ;)
另外,这在Android中不起作用,它不支持在向后看中使用\G
import static java.lang.System.exit;
import java.util.Scanner;
import Java.util.Arrays.*;
public class string123 {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("Enter String");
String r=sc.nextLine();
String[] s=new String[10];
int len=r.length();
System.out.println("Enter length Of Sub-string");
int l=sc.nextInt();
int last;
int f=0;
for(int i=0;;i++){
last=(f+l);
if((last)>=len) last=len;
s[i]=r.substring(f,last);
// System.out.println(s[i]);
if (last==len)break;
f=(f+l);
}
System.out.print(Arrays.tostring(s));
}}
结果
Enter String
Thequickbrownfoxjumps
Enter length Of Sub-string
4
["Theq","uick","brow","nfox","jump","s"]
@Test
public void regexSplit() {
String source = "Thequickbrownfoxjumps";
// define matcher, any char, min length 1, max length 4
Matcher matcher = Pattern.compile(".{1,4}").matcher(source);
List<String> result = new ArrayList<>();
while (matcher.find()) {
result.add(source.substring(matcher.start(), matcher.end()));
}
String[] expected = {"Theq", "uick", "brow", "nfox", "jump", "s"};
assertArrayEquals(result.toArray(), expected);
}
public static String[] split(String src, int len) {
String[] result = new String[(int)Math.ceil((double)src.length()/(double)len)];
for (int i=0; i<result.length; i++)
result[i] = src.substring(i*len, Math.min(src.length(), (i+1)*len));
return result;
}