我想实现Java中的String.split()方法,但不是通过调用split()方法。
例如,调用“逗号,分隔,值”.split(“,”, - 1)将为我提供3个值。现在我想实现同样的目的,但是使用正则表达式,而不是调用split()方法。
分隔符是任意的(可以包含多个字符),分割的值也应该是任意的。
我已尝试搜索之前的StackOverflow答案,人们建议使用否定前瞻,但我还没有找到适用于任意分隔符和值的精确正则表达式。
提前致谢。
PS:即将构造正则表达式时,“任意”分隔符是已知的。它作为参数传递给regex构建器。它可以是逗号,管道或多个字符的组合,例如pipe-tilde-pipe。
我理解split()本身接受正则表达式作为参数。为了说清楚,我想要的是这样的:
Pattern pattern = Pattern.compile("<the regex pattern>");
Matcher matcher = pattern.matcher("comma,separated,values");
while (matcher.find()) {
System.out.println(matcher.group());
}
以下内容将打印出来:
答案 0 :(得分:0)
一旦找到sep
或者线本身结束,值就会包含任何字符和结尾。使用惰性*?
,因此您只能转到第一个 sep
(否则您将首先运行到EOL并匹配$
):< / p>
.*?(<sep>|$)
值不包含分隔符,因此请使用捕获组单独获取它:
(.*?)(<sep>|$)
当迭代匹配时,find()
将使用该值,将其放入捕获组1
(使用group(1)
访问),然后使用分隔符,因此第二次调用{ {1}}找到下一个值和下一个分隔符。 find()
可以是任何正则表达式;如果你想拆分一个普通的字符串,你必须首先逃避它以确保安全。另外,如果你使用sep
作为正则表达式,请注意贪婪。
例如:设置sep
,它匹配可被sep = ([0369]|([258][0369]*[147])|([147]|[258]{2})([0369]|([147][0369]*[258]))*([258]|[147]{2}))+
整除的数字。然后
3
打印
Pattern pat = Pattern.compile("(.*?)(([0369]|([258][0369]*[147])|([147]|[258]{2})([0369]|([147][0369]*[258]))*([258]|[147]{2}))+|$)");
Matcher mat = pat.matcher("a333521c63");
while(mat.find()) {
System.out.println("Field: " + mat.group(1) + "; Terminated by: " + mat.group(2));
}
请注意,如果您必须使用Field: a; Terminated by: 333
Field: 5; Terminated by: 21
Field: c; Terminated by: 63
Field: ; Terminated by:
(又名group()
)而不是group(0)
,那么您必须使用lookarounds,这会产生此正则表达式
group(1)
由于(?<=<sep>|^).*?(?=<sep>|$)
位于lookbehind内,因此您无法在其中使用sep
,+
或*
,因为它是Java regex引擎的限制,它不能处理潜在无限大小的外观(公平地说,大多数其他引擎更具限制性)。它适用于您的简单用例,逗号和固定字符串
{n,}
它甚至适用于此:
Commas: (?<=,|^).*?(?=,|$)
|~| : (?<=\|~\||^).*?(?=\|~\||$)
但它不适用于数字 - 可分割 - Snake : (?<=s{0,10}!|^).*?(?=s{0,10}!|$)
:
3
示例:
Div-by-3: (?<=([0369]|([258][0369]*[147])|([147]|[258]{2})([0369]|([147][0369]*[258]))*([258]|[147]{2}))+|^).*?(?=([0369]|([258][0369]*[147])|([147]|[258]{2})([0369]|([147][0369]*[258]))*([258]|[147]{2}))+|$)
^ ERROR! * in lookbehind
输出:
Pattern asSeparator(String sep) {
return Pattern.compile("(?<=(" + sep + ")|^).*?(?=(" + sep + ")|$)");
}
String[] seps = { ","
, "\\|~\\|"
, "s{0,10}!"
, "([0369]|([258][0369]*[147])|([147]|[258]{2})([0369]|([147][0369]*[258]))*([258]|[147]{2}))+"
};
for(String sep : seps) {
System.out.println("Separator: " + sep);
Pattern pat = asSeparator(sep);
Matcher mat = pat.matcher("a3a,|~|, sssss!6");
while(mat.find()) {
System.out.println(mat.group());
}
System.out.println();
}