java/scala:正则表达式,用于在拆分字符串时跳过奇数个反斜杠



这是我的要求:

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");
    }

让我们更深入地了解正则表达式。我将把它分成两部分:

  1. 数出现分号(;)时拆分后跟一个竖线("|"):
    (?<!;)(;;)+\| :在这里,我们确保与 (;;) 匹配偶数+ 和一个后视,以确保我们在偶数出现之前没有匹配任何意外的";"。

  2. 在管道上拆分,不带前面的分号: (?<!;)\| : 在这里,我们将只匹配单独的管道符号,并使用后视来确保在"|"之前没有";"

上述代码段的输出

希望这有帮助! :)

最新更新