如何在java中从右侧开始分割带有限制的字符串?

时间:2023-02-08 21:47:20

Split without limits split the entire string but if you set a limit it splits up to that limit by the left. How can I do the same by the right?

无限制拆分会拆分整个字符串,但如果设置了限制,则会向左拆分该限制。我怎么能在右边这样做呢?

"a.b.c".split("[.]", 2); // returns ["a", "b.c"]

I would want

我想要

"a.b.c".splitRight("[.]", 2); // to return ["a.b", "c"]

EDIT: I want a general solution that works just like splited but reversed so I add a more complex example

编辑:我想要一个通用的解决方案,就像分裂但反转,所以我添加一个更复杂的例子

I would want

我想要

"a(->)b(->)c(->)d".splitRight("\\(->\\)", 3); // to return ["a(->)b", "c", "d"]

3 个解决方案

#1


1  

I would try with something like this:

我会尝试这样的事情:

public List<String> splitRight(String string, String regex, int limit) {
    List<String> result = new ArrayList<String>();
    String[] temp = new String[0];
    for(int i = 1; i < limit; i++) {
        if(string.matches(".*"+regex+".*")) {
            temp = string.split(modifyRegex(regex));
            result.add(temp[1]);
            string = temp[0];
        }
    }
    if(temp.length>0) { 
        result.add(temp[0]);
    }
    Collections.reverse(result);
    return result;
}

public String modifyRegex(String regex){
    return regex + "(?!.*" + regex + ".*$)";
}

The regular expression for split is wrapped by another, so for \\., you will get: \\.(?!.*\\..*$), to match and split on last occurance of delimiter. The string is splitted multiple time with this regex, the second element of result array is added to List, next split is done on first element of result array.

split的正则表达式由另一个包装,因此对于\\。,您将得到:\\。(?!。* \\ .. * $),以匹配并拆分最后一次出现的分隔符。使用此正则表达式将字符串多次拆分,将结果数组的第二个元素添加到List,然后在结果数组的第一个元素上完成下一个拆分。

The effect of above method for your example string is as expected.

上面的方法对您的示例字符串的效果是预期的。

#2


5  

You may use look-ahead match:

您可以使用先行匹配:

"a.b.c".split("[.](?=[^.]*$)")

Here you say "I want to split by only that dot which has no other dots after it".

在这里你说“我想只通过它之后没有其他点的点”。

If you want to split by last N dots, you can generalize this solution in this (even more ugly way):

如果你想分割最后N个点,你可以用这个来概括这个解决方案(甚至更丑陋):

"dfsga.sdgdsb.dsgc.dsgsdfg.dsdg.sdfg.sdf".split("[.](?=([^.]*[.]){0,3}[^.]*$)");

Replace 3 with N-2.

用N-2代替3。

However I would write a short static method instead:

但是我会写一个简短的静态方法:

public static String[] splitAtLastDot(String s) {
    int pos = s.lastIndexOf('.');
    if(pos == -1)
        return new String[] {s};
    return new String[] {s.substring(0, pos), s.substring(pos+1)};
}

#3


2  

Despite that you said reversing would take to long, here´s a small programm that reveres the String and splits it by the limit;

尽管你说逆转需要花费很长时间,但这是一个小程序,它尊重String并将其分割为极限;

static String[] leftSplit(String input, String regex, int limit) {
    String reveresedInput = new StringBuilder(input).reverse().toString();
    String[] output = reveresedInput.split(regex, limit);
    String tempOutput[] = new String[output.length];
    for(int i = 0;i<output.length;++i) {
        tempOutput[tempOutput.length-i-1] = new StringBuilder(output[i]).reverse().toString();
    }
    return tempOutput;
}

public static void main(String[] args) {
    System.out.println(Arrays.toString(leftSplit("a.b.c", "[.]", 2)));
    System.out.println(Arrays.toString(leftSplit("I want to. Split this. by the. right side", "[.]", 2)));
}

#1


1  

I would try with something like this:

我会尝试这样的事情:

public List<String> splitRight(String string, String regex, int limit) {
    List<String> result = new ArrayList<String>();
    String[] temp = new String[0];
    for(int i = 1; i < limit; i++) {
        if(string.matches(".*"+regex+".*")) {
            temp = string.split(modifyRegex(regex));
            result.add(temp[1]);
            string = temp[0];
        }
    }
    if(temp.length>0) { 
        result.add(temp[0]);
    }
    Collections.reverse(result);
    return result;
}

public String modifyRegex(String regex){
    return regex + "(?!.*" + regex + ".*$)";
}

The regular expression for split is wrapped by another, so for \\., you will get: \\.(?!.*\\..*$), to match and split on last occurance of delimiter. The string is splitted multiple time with this regex, the second element of result array is added to List, next split is done on first element of result array.

split的正则表达式由另一个包装,因此对于\\。,您将得到:\\。(?!。* \\ .. * $),以匹配并拆分最后一次出现的分隔符。使用此正则表达式将字符串多次拆分,将结果数组的第二个元素添加到List,然后在结果数组的第一个元素上完成下一个拆分。

The effect of above method for your example string is as expected.

上面的方法对您的示例字符串的效果是预期的。

#2


5  

You may use look-ahead match:

您可以使用先行匹配:

"a.b.c".split("[.](?=[^.]*$)")

Here you say "I want to split by only that dot which has no other dots after it".

在这里你说“我想只通过它之后没有其他点的点”。

If you want to split by last N dots, you can generalize this solution in this (even more ugly way):

如果你想分割最后N个点,你可以用这个来概括这个解决方案(甚至更丑陋):

"dfsga.sdgdsb.dsgc.dsgsdfg.dsdg.sdfg.sdf".split("[.](?=([^.]*[.]){0,3}[^.]*$)");

Replace 3 with N-2.

用N-2代替3。

However I would write a short static method instead:

但是我会写一个简短的静态方法:

public static String[] splitAtLastDot(String s) {
    int pos = s.lastIndexOf('.');
    if(pos == -1)
        return new String[] {s};
    return new String[] {s.substring(0, pos), s.substring(pos+1)};
}

#3


2  

Despite that you said reversing would take to long, here´s a small programm that reveres the String and splits it by the limit;

尽管你说逆转需要花费很长时间,但这是一个小程序,它尊重String并将其分割为极限;

static String[] leftSplit(String input, String regex, int limit) {
    String reveresedInput = new StringBuilder(input).reverse().toString();
    String[] output = reveresedInput.split(regex, limit);
    String tempOutput[] = new String[output.length];
    for(int i = 0;i<output.length;++i) {
        tempOutput[tempOutput.length-i-1] = new StringBuilder(output[i]).reverse().toString();
    }
    return tempOutput;
}

public static void main(String[] args) {
    System.out.println(Arrays.toString(leftSplit("a.b.c", "[.]", 2)));
    System.out.println(Arrays.toString(leftSplit("I want to. Split this. by the. right side", "[.]", 2)));
}