wandermonk
wandermonk

Reputation: 7356

How to replace tokens in java using regex?

I am having a string template containing $variables which needs to be replaced.

String Template: "hi my name is $name.\nI am $age old. I am $sex"

The solution which i tried verifying does not work in the java program. http://regexr.com/3dtq1

Further, I referred to https://www.regex101.com/ where i could not check if the pattern works for java. But, while going through one of the tutorials I found that "$ Matches end of line". what's the best way to replace the tokens in the template with the variables?

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class PatternCompiler {
    static String text = "hi my name is $name.\nI am $age old. I am $sex";
    static Map<String,String> replacements = new HashMap<String,String>();
    static Pattern pattern = Pattern.compile("\\$\\w+");
    static Matcher matcher = pattern.matcher(text);

    public static void main(String[] args) {

        replacements.put("name", "kumar");
        replacements.put("age", "26");
        replacements.put("sex", "male");

        StringBuffer buffer = new StringBuffer();

        while (matcher.find()) {
            String replacement = replacements.get(matcher.group(1));
            if (replacement != null) {
                // matcher.appendReplacement(buffer, replacement);
                // see comment 
                matcher.appendReplacement(buffer, "");
                buffer.append(replacement);
            }
        }
        matcher.appendTail(buffer);
        System.out.println(buffer.toString());


    }

}

Upvotes: 1

Views: 1392

Answers (4)

Drgabble
Drgabble

Reputation: 628

Your not using the right thing as your key. Change to group(), and change map to '$name' etc:

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class HelloWorld {
    static String text = "hi my name is $name.\nI am $age old. I am $sex";
    static Map<String,String> replacements = new HashMap<String,String>();
    static Pattern pattern = Pattern.compile("\\$\\w+");
    static Matcher matcher = pattern.matcher(text);

    public static void main(String[] args) {

        replacements.put("$name", "kumar");
        replacements.put("$age", "26");
        replacements.put("$sex", "male");

        StringBuffer buffer = new StringBuffer();

        while (matcher.find()) {
            String replacement = replacements.get(matcher.group());
            System.out.println(replacement);
            if (replacement != null) {
                // matcher.appendReplacement(buffer, replacement);
                // see comment 
                matcher.appendReplacement(buffer, "");
                buffer.append(replacement);
            }
        }
        matcher.appendTail(buffer);
        System.out.println(buffer.toString());


    }

}

Upvotes: 0

Krzysztof Krasoń
Krzysztof Krasoń

Reputation: 27476

You are using matcher.group(1) but you didn't define any group in the regexp (( )), so you can use only group() for the whole matched string, which is what you want.

Replace line:

String replacement = replacements.get(matcher.group(1));

With:

String replacement = replacements.get(matcher.group().substring(1));

Notice the substring, your map contains only words, but matcher will match also $, so you need to search in map for "$age".substring(1)" but do replacement on the whole $age.

Upvotes: 3

FriedSaucePots
FriedSaucePots

Reputation: 1352

You can try replacing the pattern string with

\\$(\\w+)

and the variable replacement works. Your current pattern only has group 0 (the entire pattern) but not group 1. Adding the parenthesis makes the first group the variable name and the replacement will replace the dollar sign and the variable name.

Upvotes: 1

Joop Eggen
Joop Eggen

Reputation: 109567

Your code has just minor glitches.

    static Map<String,String> replacements = new HashMap<>();
    static Pattern pattern = Pattern.compile("\\$\\w+\\b"); // \b not really needed

            // As no braces (...) there is no group(1)
            String replacement = replacements.get(matcher.group());

Upvotes: 0

Related Questions