Java PatternSyntaxException: Illegal repetition on string substitution?

后端 未结 5 1773
萌比男神i
萌比男神i 2020-12-03 13:39

I am trying to write a method that will accept a String, inspect it for instances of certain tokens (e.g. ${fizz}, ${buzz}, ${fo

相关标签:
5条回答
  • 2020-12-03 13:45

    Adapted from Matcher.replaceAll

    boolean result = matcher.find();
    if (result) {
        StringBuffer sb = new StringBuffer();
        do {
            String tokenKey = matcher.group(1); // Ex: fizz
            String replacement = Matcher.quoteReplacement(tokensMap.get(tokenKey));
            matcher.appendReplacement(sb, replacement);
            result = matcher.find();
        } while (result);
        matcher.appendTail(sb);
        return sb.toString();
    }
    
    0 讨论(0)
  • 2020-12-03 13:49

    Use String-replaceAll. Sample input String for testing "SESSIONKEY1":

    "${SOMESTRING.properties.SESSIONKEY1}"

    ,

        String pattern = "\\\"\\$\\{SOMESTRING\\.[^\\}]+\\}\\\""; 
        System.out.println(pattern);
        String result = inputString.replaceAll(pattern, "null");
        return result.toString();
    
    0 讨论(0)
  • 2020-12-03 14:03

    As pointed out by Patashu, the problem is in replaceFirst(token, replacementValue), that expects a regex in the first argument, not a literal. Change it to replaceFirst(Pattern.quote(token), replacementValue) and you will do alright.

    I also changed a bit the first regex, as it goes faster with + instead of * but that's not necessary.

    static String substituteAllTokens(Map<String,String> tokensMap, String toInspect) {
        String regex = "\\$\\{([^}]+)\\}";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(toInspect);
        String result = toInspect;
        while(matcher.find()) {
            String token = matcher.group();     // Ex: ${fizz}
            String tokenKey = matcher.group(1); // Ex: fizz
            String replacementValue = null;
    
            if(tokensMap.containsKey(tokenKey))
                replacementValue = tokensMap.get(tokenKey);
            else
                throw new RuntimeException("String contained an unsupported token.");
    
            result = result.replaceFirst(Pattern.quote(token), replacementValue);
        }
    
        return result;
    }
    
    0 讨论(0)
  • You can make your RegEx a bit ugly, but this will work

    String regex = "\\$[\\{]([^}]*)[\\}]";
    
    0 讨论(0)
  • 2020-12-03 14:09

    In ${fizz}

    { is an indicator to the regex engine that you are about to start a repetition indicator, like {2,4} which means '2 to 4 times of the previous token'. But {f is illegal, because it has to be followed by a number, so it throws an exception.

    You need to escape all regex metacharacters (in this case $, { and }) (try using http://docs.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html#quote(java.lang.String) ) or use a different method that substitutes a string for a string, not a regex for a string.

    0 讨论(0)
提交回复
热议问题