string按照分割 - 在Java中将字符串拆分为长度相等的子字符串




text split java (9)

如何将字符串"Thequickbrownfoxjumps"拆分为Java中的大小相同的子字符串。 例如。 4个相同大小的"Thequickbrownfoxjumps"应该给出输出。

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

类似问题:

将字符串拆分为Scala中的等长子字符串


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) 

把它放在一个循环中,你很好走。


如果你使用Google的guava通用库(老实说,任何新的Java项目可能都应该是这样),这对Splitter类来说是非常微不足道的:

for (String substring : Splitter.fixedLength(4).split(inputString)) {
    doSomethingWith(substring);
}

就是这样 。 简单!


如果您想要将字符串向后均分(即从右向左),例如将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;
}




split