0

If I got a String="#1 and #2", a Map={"1":"a", "2":"b"}, What I indend to do is to replace #x with the value evaluated from Map(x), whose result should be "a and b".

My code is as follows:

Map<String, String> map = new HashMap<String, String>();
    map.put("1", "a");
    map.put("2", "b");
    String s = "#1 and #2";
    Pattern p = Pattern.compile("#(.*?)(\\s|$)");
    Matcher m = p.matcher(s);
    while(m.find())        {
        s = m.replaceFirst(m.group(1));
        System.out.println(s);
}

But the output is infinite like:

1and #2
2and #2
2and #2
2and #2
...
...

Could anyone give me an explanation on this phenomennon, as well as give me a proper solution to my problem? Thanks a lot!

Judking
  • 6,111
  • 11
  • 55
  • 84
  • http://stackoverflow.com/questions/24256469/replacing-contents-inside-curly-braces-for-e-g-1-with-something-else?noredirect=1#comment37470934_24256469 might help – TheLostMind Jun 22 '14 at 07:37
  • Thanks bro, this helps. But could you explain why my code would end up with an infinite loop? @TheLostMind – Judking Jun 22 '14 at 07:40
  • The regex is partially wrong.. and you are replacing s by calling replaceFirst on the matcher. – TheLostMind Jun 22 '14 at 07:55

2 Answers2

2

Change your regex pattern to #(\d+) to make it simple.

Sample code 1: (using String#replaceAll())

Map<String, String> map = new HashMap<String, String>();
map.put("1", "a");
map.put("2", "b");
String s = "#1 and #2";
Pattern p = Pattern.compile("#(\\d+)");
Matcher m = p.matcher(s);
while (m.find()) {
    String match = m.group(1);
    s = s.replaceAll("#"+match, map.get(match));
}
System.out.println(s);

Sample code 2: (using Matcher#appendReplacement())

Map<String, String> map = new HashMap<String, String>();
map.put("1", "a");
map.put("2", "b");
String s = "#1 and #2";
Pattern p = Pattern.compile("#(\\d+)");
Matcher m = p.matcher(s);
StringBuffer buffer = new StringBuffer();
while (m.find()) {
    m.appendReplacement(buffer, map.get(m.group(1)));
}
System.out.println(buffer);

Please have a look at Matcher's documentation, where a lot more stuff is covered in detail.

The post Java Regex Replace with Capturing Group might help you to understand it better.

Community
  • 1
  • 1
Braj
  • 46,415
  • 5
  • 60
  • 76
0
    Map<String, String> map = new HashMap<String, String>();
    map.put("1", "a");
    map.put("2", "b");
    String s = "#1 and #2";
    String result = null ;
    Pattern p = Pattern.compile("#(\\d+).*#(\\d)");
    Matcher m = p.matcher(s);
    if(m.find()){
       result = s.replaceFirst("#\\d+", map.get(m.group(1)));
       result = result.replaceFirst("#\\d+", map.get(m.group(2)));
    }
    System.out.println(result);
bcmeng
  • 1