我有一个字符串,长这样:
0,0,1,2,4,5,3,4,6
我希望返回的是一个被分割后每三个逗号一组的
String[]
数组,结果应该如下所示:[ "0,0,1", "2,4,5", "3,4,6" ]
我找到了类似的函数,但它们不会在第n个逗号处分割。
注意:虽然使用split
方法的解决方案可能有效(在Java 17上的最后一个测试中),但是它基于一个错误,因为Java中的前瞻应该具有明显的最大长度。理论上,这种限制应该防止我们使用+
,但是某种方式上,以\G
开头让我们在这里使用+
。在未来,这个错误可能会被修复,这意味着split
将停止工作。
更安全的方法是使用Matcher#find
,如下所示:
String data = "0,0,1,2,4,5,3,4,6";
Pattern p = Pattern.compile("\\d+,\\d+,\\d+");//no look-ahead needed
Matcher m = p.matcher(data);
List<String> parts = new ArrayList<>();
while(m.find()){
parts.add(m.group());
}
String[] result = parts.toArray(new String[0]);
你可以尝试使用 split
方法,配合正则表达式 (?<=\\G\\d+,\\d+,\\d+),
Demo
String data = "0,0,1,2,4,5,3,4,6";
String[] array = data.split("(?<=\\G\\d+,\\d+,\\d+),"); //Magic :)
// to reveal magic see explanation below answer
for(String s : array){
System.out.println(s);
}
输出:
0,0,1
2,4,5
3,4,6
解释
\\d
表示一个数字,等同于 [0-9],如 0
或者 3
\\d+
表示一个或多个数字,如 1
或者 23
\\d+,
表示一个或多个数字后跟逗号,如 1,
或者 234,
\\d+,\\d+,\\d+
表示接受三个数字,中间由逗号分隔,如 12,3,456
\\G
表示上一个匹配,或者(在第一次匹配时)字符串的开头(?<=...),
是正向先行断言,它将匹配前面有描述在(?<=...)
的字符和逗号,
(?<=\\G\\d+,\\d+,\\d+),
尝试找到有三个数字的逗号,在这个逗号之前有字符串的开始(如你的例子中的^0,0,1
)或者之前匹配的逗号,如 2,4,5
和 3,4,6
。此外,如果你想使用非数字的字符,你也可以使用其他一组字符,如下所示:
\\w
匹配字母、数字和下划线_
\\S
匹配所有不是空格的字符[^,]
匹配所有不是逗号的字符顺便提一下,这个表单将在第三个、第五个、第七个(以及其他奇数)逗号处分割,例如:split("(?<=\\G\\w+,\\w+,\\w+,\\w+,\\w+),")
将在每个第五个逗号处分割。
要在第二个、第四个、第六个、第八个(以及其他偶数)逗号处分割,你需要用 {1,maxLengthOfNumber}
替换 +
,例如:split("(?<=\\G\\w{1,3},\\w{1,3},\\w{1,3},\\w{1,3}),")
,将在每个第四个逗号处分割,当数字最多有三位数(0、00、12、000、123、412、999)时。
要在每个第二个逗号处分割,你也可以使用这个正则表达式 split("(?<!\\G\\d+),")
,基于我的先前的回答
\\d
。无论如何,非常感谢您提供的额外信息,我会将其包含在答案中。 - Pshemo.split("(?<=\\G\\d{1,100}(,\\d{1,100}){"+n+"}),")
的内容,那么很遗憾,这将不起作用(很难解释为什么正则表达式无法确定此处的最大长度,因为n
将表示现有值)。 - Pshemo必备的 Guava 答案:
String input = "0,0,1,2,4,5,3,4,6";
String delimiter = ",";
int partitionSize = 3;
for (Iterable<String> iterable : Iterables.partition(Splitter.on(delimiter).split(s), partitionSize)) {
System.out.println(Joiner.on(delimiter).join(iterable));
}
输出:
0,0,1
2,4,5
3,4,6
类似下面这样:
public String[] mySplitIntoThree(String str)
{
String[] parts = str.split(",");
List<String> strList = new ArrayList<String>();
for(int x = 0; x < parts.length - 2; x = x+3)
{
String tmpStr = parts[x] + "," + parts[x+1] + "," + parts[x+2];
strList.add(tmpStr);
}
return strList.toArray(new String[strList.size()]);
}
n
是目前找到的部分数量,
i
是下一个部分的开始,
startIndex
是当前子字符串的开始。List<String> result = new ArrayList<String>();
int startIndex = 0;
int n = 0;
for (int i = x.indexOf(',') + 1; i > 0; i = x.indexOf(',', i) + 1, n++) {
if (n % 3 == 2) {
result.add(x.substring(startIndex, i - 1));
startIndex = i;
}
}
result.add(x.substring(startIndex));
0,0,1,2,4,5,3,4,6
改成0,0,1|2,4,5|3,4,6
,这是一种相当简单的正则表达式替换转换。或者,直接使用Matcher并逐步遍历它(如此处所示)。 - user2246674indexOf
,另一种是先按逗号分割,然后再将结果按三个一组重新拼接起来。 - flup