0

I have a small api to convert a string to another string by updating property holders (pattern {{property_name}}

Here is my try:

public class TestApp {

    public static void main(String[] args) {
        Map<String, String> props = new HashMap<>();
        props.put("title", "login");

        String sourceTitle = "<title>{{ title }}</title>";
        System.out.println(updatePropertyValue(sourceTitle, props));

        // Print: <title>login</title>

        // ERROR if
        props.put("title", "${{__messages.loginTitle}}");
        System.out.println(updatePropertyValue(sourceTitle, props));
        // Expected: <title>${{__messages.loginTitle}}</title>

        // Exception:

        // Exception in thread "main" 
        // java.lang.IllegalArgumentException: named capturing group has 0 length name
        // at java.util.regex.Matcher.appendReplacement(Matcher.java:838)
    }

    static String updatePropertyValue(String line, Map<String, String> properties) {
        for (Entry<String, String> entry : properties.entrySet()) {
            String holder = "\\{\\{\\s*" + entry.getKey() + "\\s*\\}\\}";
            line = Pattern.compile(holder, Pattern.CASE_INSENSITIVE)
                          .matcher(line).replaceAll(entry.getValue());
        }
        return line;
    }
}

It works fine If the property value does not have any special characters such as $.

Please assume that property keys include letters only.

Any solution? Thanks!

LHA
  • 9,398
  • 8
  • 46
  • 85
  • Have you looked at the [documentation of the `replaceAll` method](https://docs.oracle.com/javase/7/docs/api/java/util/regex/Matcher.html#replaceAll(java.lang.String))? Especially what it says about dollar signs? – RealSkeptic Jan 03 '17 at 17:12
  • @RealSkeptic: Yes, I took a look at it. What I need is there is another solution for it. Thanks! – LHA Jan 03 '17 at 17:13
  • 1
    Use `.replaceAll(entry.getValue().replace("$", "\\$"))` in the `updatePropertyValue` method. – Wiktor Stribiżew Jan 03 '17 at 17:16
  • 2
    Well, as it says in the same documentation, add a backslash before the `$`, and the problem will be solved. – RealSkeptic Jan 03 '17 at 17:17
  • Thank you!. I thought I need to have a list of special chars. Not only $. But it seems $ is enough. – LHA Jan 03 '17 at 17:21

2 Answers2

3

Use Pattern.quoteReplacement to escape all metacharacters in the replacement.

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
0

I guess you need to regex escape entry.getKey() part. This should help in doing that.

Community
  • 1
  • 1
Abhishek Bhatia
  • 716
  • 9
  • 26