这是我的要求:
Input1: adasd|adsasd|adsadsadad|asdsad
output1: Array(adasd,adsasd|adsadsadad,asdsad)
Input2: adasd|adsasd\|adsadsadad|asdsad
output2: Array(adasd,adsasd\,adsadsadad,asdsad)
Input3: adasd|adsasd\|adsadsadad|asdsad
output3: Array(adasd,adsasd\|adsadsadad,asdsad)
我正在使用以下代码:
val delimiter =Pattern.quote("|")
val esc = "\"
val regex = "(?<!" + Pattern.quote(esc) + ")" + delimiter
但这并非适用于所有情况。
解决这个问题的最佳解决方案是什么?
不要拆分,而是使用此正则表达式进行匹配:
(?<=[|]|^)[^|\]*(?:\.[^|\]*)*
Java 代码演示
爪哇代码:
final String[] input = {"adasd|adsasd\|adsadsadad|asdsad",
"adasd|adsasd\\|adsadsadad|asdsad",
"adasd|adsasd\\\|adsadsadad|asdsad"};
final String regex = "(?<=[|]|^)[^|\\]*(?:\\.[^|\\]*)*";
final Pattern pattern = Pattern.compile(regex);
Matcher matcher;
for (String string: input) {
matcher = pattern.matcher(string);
System.out.println("n*** Input: " + string);
while (matcher.find()) {
System.out.println(matcher.group(0));
}
}
输出:
*** Input: adasd|adsasd|adsadsadad|asdsad
adasd
adsasd|adsadsadad
asdsad
*** Input: adasd|adsasd\|adsadsadad|asdsad
adasd
adsasd\
adsadsadad
asdsad
*** Input: adasd|adsasd\|adsadsadad|asdsad
adasd
adsasd\|adsadsadad
asdsad
为了简单起见,让我们使用 ";"(分号)而不是"\"(反斜杠),以避免此处出现太多转义序列。
我们可以通过如下所示的回顾来完成此拆分:
String[] input = { "adasd|zook;|adsadsadad|asdsad", "adasd|zook;;|adsadsadad|asdsad",
"adasd|zook;;;|adsadsadad|asdsad", "blah;|blah;;;;|blah|blahblah;|blahbloooh;;|" };
String regex = "(?<!;)(;;)+\||(?<!;)\|";
for(String str : input) {
System.out.println("Input : "+ str);
System.out.println("Output: ");
String[] astr = str.split(regex);
for(String nres : astr)
System.out.print(nres+", ");
System.out.println("n");
}
让我们更深入地了解正则表达式。我将把它分成两部分:
- 偶
数出现分号(;)时拆分后跟一个竖线("|"):
(?<!;)(;;)+\|
:在这里,我们确保与 (;;) 匹配偶数+ 和一个后视,以确保我们在偶数出现之前没有匹配任何意外的";"。在管道上拆分,不带前面的分号:
(?<!;)\|
: 在这里,我们将只匹配单独的管道符号,并使用后视来确保在"|"之前没有";"
上述代码段的输出
希望这有帮助! :)