代码之家  ›  专栏  ›  技术社区  ›  Zac

使用重复捕获替换regex

  •  2
  • Zac  · 技术社区  · 15 年前

    我有一张桌子,像:

    A | 1  
    A | 2  
    B | 1  
    B | 2  
    B | 3
    

    我想把它变成这样:

    A { 1 | 2 }  
    B { 1 | 2 | 3 }
    

    我想出了一个正确匹配的方法,我就是不知道如何把重复捕捉出来。

    (A|B)|(\d)(\r\n\1|(\d))*
    

    更新

    我意识到对于某些编程语言来说,这是相当微不足道的,我希望了解更多关于正则表达式的内容。

    1 回复  |  直到 15 年前
        1
  •  1
  •   polygenelubricants    15 年前

    这是一个Java代码,可能会有帮助:

        String text =   "A | 1\n" +
                        "A | 2\n" +  
                        "B | 1\n" +
                        "B | 2\n" +
                        "B | 3\n" +
                        "A | x\n" +
                        "D | y\n" +
                        "D | z\n";
        String[] sections = text.split("(?<=(.) . .)\n(?!\\1)");
        StringBuilder sb = new StringBuilder();
        for (String section : sections) {
            sb.append(section.substring(0, 1) + " {")
              .append(section.substring(3).replaceAll("\n.", ""))
              .append(" }\n");
        }
        System.out.println(sb.toString());
    

    印刷品:

    A { 1 | 2 }
    B { 1 | 2 | 3 }
    A { x }
    D { y | z }
    

    我们的想法是分两步进行:

    • 首先,分成若干部分
    • 然后变换每个部分

    单一的 replaceAll 变体

    如果你穿插 { } 在要捕获的输入中,以便在输出中重新排列它们,这可以通过一个 替换所有 (即 完全正则表达式 解决方案)

    String text =   "{ A | 1 }" +
                    "{ A | 2 }" +
                    "{ B | 1 }" + 
                    "{ B | 2 }" +
                    "{ B | 3 }" +
                    "{ C | 4 }" +
                    "{ D | 5 }";
    System.out.println(
        text.replaceAll("(?=\\{ (.))(?<!(?=\\1).{7})(\\{)( )(.) .|(?=\\}. (.))(?:(?<=(?=\\5).{6}).{5}|(?<=(.))(.))", "$4$3$2$7$6")
    );
    

    这张照片( see output on ideone.org ):

    A { 1 | 2 } B { 1 | 2 | 3 } C { 4 } D { 5 }
    

    不幸的是,不,我认为这不值得解释。对于正在完成的任务来说,这太复杂了。实际上,尽管如此,许多断言、嵌套断言和捕获组(其中一些将是空字符串,具体取决于哪个断言传递)。

    毫无疑问,这是我写的最复杂的正则表达式。