2

My program is as below,

    /**
     * @param args
     */
    public static void main(String[] args) {
        RegularExpressions r = new RegularExpressions();
        // TODO Auto-generated method stub
        String []input = {" Dear [name],\n",
                "\n",
                "Thanks for buying the [num] [item].\n",
                "We appreciate your patronage\n",
                "\n",
                "Best, [sales_person]\n"};
        HashMap<String, String> dic = new HashMap<String, String>();
        dic.put("name", "Anna Bell Smith");
        dic.put("num", "eight");
        dic.put("item", "Boxes of Soap.");
        dic.put("sales_person", "Karmine Smithe");
        String []afterChange = r.replace(input, dic);
        r.display(afterChange);

    }
    String [] replace(String []strings, Map<String, String> dict){
        String patternStr = ".(";
        for(String key:dict.keySet()){
            patternStr = patternStr + key + "|";
        }
        patternStr = patternStr.substring(0, patternStr.length()-1);
        patternStr = patternStr+").";
        Pattern pattern = Pattern.compile(patternStr);
        for(int i=0;i<strings.length;i++){
            StringBuffer sb = new StringBuffer();
            Matcher matcher = pattern.matcher(strings[i]);
            boolean isMatcherFind = false;
            while(matcher.find()){

            matcher.appendReplacement(sb, dict.get(matcher.group(1)));
                isMatcherFind = true;
            }

            if(isMatcherFind){
                strings[i] = sb.toString();
            }else{
                strings[i] = strings[i];
            }
        }
        return strings; 

    }
    void display(String []str){
        for(String s:str){
            System.out.println(s);
        }
    }
}

The above program is giving an output like

Dear Anna Bell Smith
Thanks for buying the eight Boxes of SoapWe appreciate your patronage
Best, Karmine Smithe

While I am expecting output as

Dear Anna Bell Smith


Thanks for buying the eight Boxes of Soap.
We appreciate your patronage



Best, Karmine Smithe.

Meaning, dot(.) and "\n" should be retained instead it is replacing with empty spaces. I am java 8 version, let me know how can i retain dot(.) and "\n"

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
Shakti Kumar
  • 137
  • 1
  • 7
  • 5
    You really should consider an existing templating engine, such as FreeMarker. This problem has been solved already and there's really no reason to reinvent the wheel. – Jim Garrison Feb 02 '16 at 07:31
  • I believe you meant *Wheel @JimGarrison – z7r1k3 Feb 02 '16 at 07:32
  • Like Jim said: use a templating engine. This has the additional advantage that you can keep the text outside your code which will make it easier for any non-developer to change the text if needed. – Marged Feb 02 '16 at 07:35

2 Answers2

1

You have a loop that repeatedly calls matcher.find() to find the next match in the string; then it calls appendReplacement(). The javadoc for appendReplacement says it does this:

  1. It reads characters from the input sequence, starting at the append position, and appends them to the given string buffer. It stops after reading the last character preceding the previous match, that is, the character at index start() - 1.

  2. It appends the given replacement string to the string buffer.

  3. It sets the append position of this matcher to the index of the last character matched, plus one, that is, to end().

So for each match, it appends the characters up to the match, then it appends the replacement string (instead of the string that got matched). So far, so good.

But what happens when there's no more matches? There are still characters left in the input, to the right of the last match, that didn't get appended to the output.

Fortunately, there's a method that takes care of exactly that for you: appendTail.

ajb
  • 31,309
  • 3
  • 58
  • 84
0

You'd have to use appendReplacement and appendTail explicitly. Unfortunately you have to use StringBuffer to do this. Here's a snippet:

    String content="aaaaaaaaaa";
Pattern pattern = Pattern.compile("a");
Matcher m = pattern.matcher(content);

StringBuffer sb = new StringBuffer();
final int N = 3;
for (int i = 0; i < N; i++) {
  if (m.find()) {
     m.appendReplacement(sb, "b");
  } else {
     break;
  }
}
m.appendTail(sb);
System.out.println(sb); // bbbaaaaaaa

according to matcher-replace-method

Community
  • 1
  • 1
Abdelhak
  • 8,299
  • 4
  • 22
  • 36
  • You've missed the point entirely. The dot is in the replacement string. There are no dots in the pattern that the OP is searching for. – ajb Feb 02 '16 at 07:36
  • Then why are you suggesting backslashing it? Backslashing dots only makes a difference in a pattern, not in a replacement string. Your answer is incorrect. – ajb Feb 02 '16 at 07:42