获取java.util.regex.PatternSyntaxException:尝试用replaceAll()替换String时非法重复

时间:2018-05-18 13:46:15

标签: java regex

我试图将给定字符串中的单词与正则表达式匹配

{{ some | value }}
像这样。

例如:

Hello {{ some | value }}, this is what i tried {{ another | value }}

从此我想提取

{{ some | value }} and {{ another | value }}

我尝试使用此正则表达式模式Pattern.compile("\\{\\{(.*?)\\}\\}")

当我尝试迭代所有匹配并使用replaceAll替换时,我得到了java.util.regex.PatternSyntaxException: Illegal repetition。请帮我解决这个问题。

我的代码

Pattern pattern                     = Pattern.compile("\\{\\{(.*?)\\}\\}");
Matcher matcher                     = pattern.matcher(text);
 while(matcher.find()){
            matches.add(matcher.group());
        }

for (String match : matches) 
{
    match = match.substring(2 , match.length()-2); // I WANT TO GET ONLY SOME | VALUE FROM THE PATTERN
    String splitArray[] = match.split("\\|");
    String value1 = splitArray[0].trim();
    String value2 = splitArray[1].trim();
    text = text.replaceAll(match , value1);
}

2 个答案:

答案 0 :(得分:0)

您需要的修复方法是将text = text.replaceAll(match , value1);替换为

text = text.replaceFirst(Pattern.quote(match), Matcher.quoteReplacement(value1));

它会将match的第一次出现替换为value1,其中matchvalue1都是文字字符串。

但是,我相信您希望将所有{{...|...}}替换为关键部分,而不是实际收集所有匹配/捕获。然后,使用

text.replaceAll("\\{\\{\\s*((?:(?!\\{\\{)[^|])*?)\\s*\\|\\s*(.*?)\\s*\\}\\}", "$1")

请参阅regex demo

<强>详情

  • \{\{ - {{子字符串
  • \s* - 0+ whitespaces
  • ((?:(?!\{\{)[^|])*?) - 第1组:除|以外的任何字符,0或更多,但尽可能少重复,但不启动{{序列
  • \s* - 0+ whitespaces
  • \| - |
  • \s* - 0+ whitespaces
  • (.*?) - 第2组:任意0个字符,尽可能少
  • \s* - 0+ whitespaces
  • \}\} - }}子字符串。

请参阅Java demo

String text = "Hello {{ some | value }}, this is what i tried {{ another | value }}";
text = text.replaceAll("\\{\\{\\s*((?:(?!\\{\\{)[^|])*?)\\s*\\|\\s*(.*?)\\s*\\}\\}", "$1");
System.out.println(text);
// => Hello some, this is what i tried another

请注意,如果需要,您仍然可以使用Matcher#find()提取捕获组值。

答案 1 :(得分:0)

您使用的方法似乎不必要地复杂化。查看代码,您似乎希望将{{ some | value }}替换为some,将{{ another | value }]替换为another,依此类推。那么为什么不这样做呢?

text = text.replaceAll("\\{\\{ (.+?) \\| .+? \\}\\}", "$1");

这将匹配所有实例{{ ... | ... }},并将其替换为{{|之间的部分。