greywolf82
greywolf82

Reputation: 22183

Regular expression with placeholders

I've got a string like this: "Hi $namevar$ how are you?". I want to:

  1. extract the placeholder name
  2. match against this string another string, for example "Hi jhon doe how are you?"
  3. extract from the test string the "namevar" part

For 1) I'm using the following code:

String my = "hi $namevar$ how are you?";
Matcher m = Pattern.compile("\\$(\\w.*?)\\$").matcher(my);
while (m.find()) {
    System.out.println(m.group(1));
}

Any tips for 2) and 3)?

Upvotes: 5

Views: 21854

Answers (2)

Ravi K Thapliyal
Ravi K Thapliyal

Reputation: 51711

Here's a more generic approach that doesn't require you to provide a pattern, works for multiple placeholders and can match a placeholder over multiple words too. Say, we have the following template and input string:

String input = "Hi John Doe, how are you? I'm Jane.";
String template = "Hi $namevar$, how are you? I'm $namevar2$.";

So, we parse all the placeholder names and add them to a Map first. We use a Map so that we can assign the actual String values as keys later on.

Matcher m = Pattern.compile("\\$(\\w*?)\\$").matcher(template);
Map<String, String> vars = new LinkedHashMap<String, String>();
while (m.find()) {
    System.out.println(m.group(1));
    vars.put(m.group(1), null);
}

Now, we generate the pattern to parse placeholder values as

String pattern = template;
// escape regex special characters
pattern = pattern.replaceAll("([?.])", "\\\\$1");
for (String var : vars.keySet()) {
    // replace placeholders with capture groups
    pattern = pattern.replaceAll("\\$"+var+"\\$", "([\\\\w\\\\s]+?)");
}

Now, we make a match and capture the placeholder values. The values are then stored in the same Map created above, assigned to their corresponding placeholder variables.

m = Pattern.compile(pattern).matcher(input);
if (m.matches()) {
    int i = 0;
    for (String var : vars.keySet()) {
        vars.put(var, m.group(++i));
    }
}

Now, let's print out our captured values by iterating over the Map as

for (Map.Entry<String, String> entry : vars.entrySet()) {
    System.out.println(entry.getKey() + " = " + entry.getValue());
}

Output :

namevar = John Doe
namevar2 = Jane

Upvotes: 17

SMA
SMA

Reputation: 37033

Try something like:

String mydata = "hi john how are you?";
System.out.println(mydata.matches("hi (.*?) how are you\\?"));//requirement 2
Pattern pattern = Pattern.compile("hi (.*?) how are you?");
Matcher matcher = pattern.matcher(mydata);
if (matcher.find()) {
    System.out.println(matcher.group(1));//requirement 3
}
Output:
true
john

Upvotes: 2

Related Questions