【问题标题】:Replace all text between braces { } in Java with regex用正则表达式替换Java中大括号{}之间的所有文本
【发布时间】:2013-10-03 18:23:48
【问题描述】:

我有一个长字符串,在 {} 之间出现了很多文本,但当我这样做时:

data = data.replaceAll("{(.*?)}", "");

我收到一个错误,那么我做错了什么/我应该怎么做?

【问题讨论】:

标签: java regex string


【解决方案1】:

这将替换大括号之间的所有文本并保留括号 这是通过正面展望和正面展望来完成的

data = data.replaceAll("(?<=\\{).*?(?=\\})", "");

"if (true) { calc(); }" 变成 "if (true) {}"

这将替换大括号之间的所有文本并删除括号

data = data.replaceAll("\\{.*?\\}", "");

"if (true) { calc(); }" 变成 "if (true)"

这将替换大括号之间的所有文本,包括新行。

data = Pattern.compile("(?<=\\{).*?(?=\\})", Pattern.DOTALL).matcher(data).replaceAll("");

"if (true) { \n\t\tcalc();\n }" 变为 "if (true) {}"

【讨论】:

    【解决方案2】:

    您需要转义左大括号,因为它表示量词的开始 - 正则表达式中的{n}。而且你真的不需要那个捕获组,所以删除它。

    data = data.replaceAll("\\{.*?}", "");
    

    【讨论】:

    • 试过了,没有错误,但{}之间的文字没有被删除。
    • @Jister13。你有嵌套大括号吗?
    • @Jister13。对于那个字符串,它肯定可以工作。中间有换行符吗?
    • 不,它只是把所有东西都留在那里。
    • @Jister13。只要你的字符串就像你展示的那样,这会起作用。如果您在 { 之前和之后有任何换行符。这意味着,如果您的代码是缩进的,那么这将不起作用。此外,对于任何复杂的字符串,它可能会变得更丑陋。你最好编写自己的解析器。
    【解决方案3】:

    一般来说,这是一个不适合正则表达式的工作。通常如果 "{ text }" 是可能的,那么: "{ { text1 } { text2 } }" 不能用正则表达式正确解析。

    这与 XML/HTML 解析器不使用正则表达式的原因相同

    【讨论】:

    • 那我该怎么办呢?不使用正则表达式?
    • 这完全取决于你想要什么。如果你想在没有嵌套大括号的地方接受文本,那么这很好用。或者,如果您只想删除最外面的大括号(即 { { text1 } { text2 } } 将变为“”),那么它也可以工作。但是,一旦您想解析更大的文本,并且想要在每对大括号嵌套时对其进行一些转换,它将无法正常工作。在这种情况下,使用循环手动进行解析,使用计数器跟踪开括号和闭括号将是合适的
    • 我只想删除字符串中任何大括号之间的所有文本
    • @Jister13 那么rohain的答案中的正则表达式应该可以。也许将 .*? 更改为 .* 以使其更加贪婪,并消耗所有内容,而不仅仅是第一个右括号。
    • 不,因为这会将“a { b } c { d } e”变成“a e”。如果没有嵌套,你可以使用“\\{[^}]*}”,但这确实需要一个解析器。
    【解决方案4】:

    试试这个,希望对你有帮助。

    String refinedData = new String(data);
    Pattern p = Pattern.compile("\\{[^\\}]*\\}");
    Matcher m = p.matcher(data);
    while(m.find()){
        String d = data.substring(m.start(), m.end());
        refinedData = refinedData.replace(d, "");
    }
    

    【讨论】:

    • 不,不要那样做。如果正则表达式与预期匹配,它将在 OP 的代码中工作(即data = data.replaceAll("\\{[^\\}]*\\}", "");)。在while (matcher.find()) 循环中执行replace() 是毫无意义的。
    • @AlanMoore 除非您想根据匹配值添加一些条件。 (例如,用字符替换十六进制值,用空格替换 (0x20))。
    【解决方案5】:

    当您需要匹配从一个 单个字符 到另一个 单个 字符的子字符串时,最好的正则表达式解决方案是使用分隔符并在它们之间插入一个negated character class 匹配除分隔符以外的任何字符。

    所以,基本伪模式

    a  [^ ab  ]*  b
    

    地点:

    • a - 起始分隔符
    • [^ab]* - 除了ab 之外的零个或多个字符
    • b - 尾随分隔符。

    因此,要替换 {}(大括号之间)之间的所有文本,请使用

    String data = "text 1 {\ntext 2\ntext 3\n}";
    System.out.println(data.replaceAll("\\{[^{}]*}", ""));
    // => text 1
    

    IDEONE demo

    请注意,在 Java 正则表达式中,{} 不必在字符类内部转义,} 即使在其外部也不必转义。只有{字符类之外必须转义(或放入字符类),以免形成限制量词构造。

    【讨论】:

      猜你喜欢
      • 2016-09-20
      • 2016-07-21
      • 2012-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-14
      • 1970-01-01
      • 2011-01-25
      相关资源
      最近更新 更多