-1

Input String:

<#if (${val1}-${val2}) + ${f1(${a}+${b}*${c})} > 2000>ABC<#elseif ${n1}+${n2}* ${f1(${n3}-${n4})} < 500>DEF</#if>

We want to remove All ${ and } that are present in <#if and <#elseif, apart from the ones that are present inside f1() (${ associated with f1 should get removed as well). So, the expected output string is:

<#if (val1-val2) + f1(${a}+${b}*${c}) > 2000>ABC<#elseif n1+n2*f1(${n3}-${n4}) < 500>DEF</#if>
BackSlash
  • 21,927
  • 22
  • 96
  • 136
Naman
  • 49
  • 6
  • i have tried this textToReplace=textToReplace.replaceAll("(?<=(?!<#else>)<#|\\|\\||&&)(.+?)\\$\\{(.+?)\\}", "$1$2"); but it seems to remove just 1 ${} – Naman Jul 18 '14 at 08:39

2 Answers2

1

This problem is a classic case of the technique explained in this question to "regex-match a pattern, excluding..."

We can solve it with a beautifully-simple regex:

f1\([^)]*\)|(\$\{|\})

The left side of the alternation | matches complete f1( things ). We will ignore these matches. The right side matches and captures ${ and } to Group 1, and we know they are the right ones because they were not matched by the expression on the left.

This program shows how to use the regex:

Pattern regex = Pattern.compile("f1\\([^)]*\\)|(\\$\\{|\\})");
Matcher m = regex.matcher(subject);
StringBuffer b= new StringBuffer();
while (m.find()) {
    if(m.group(1) != null) m.appendReplacement(b, "");
    else m.appendReplacement(b, m.group(0) );
}
m.appendTail(b);
String replaced = b.toString();
System.out.println(replaced);

Reference

Community
  • 1
  • 1
zx81
  • 41,100
  • 9
  • 89
  • 105
0

Regex:

(?<=if \(|elseif )\$\{([^}]*)\}([+-])\$\{([^}]*)\}

Replacement:

\1\2\3

DEMO

Your code would be,

String s1 = "<#if (${val1}-${val2}) + ${f1(${a}+${b}*${c})} > 2000>ABC<#elseif ${n1}+${n2}* ${f1(${n3}-${n4})} < 500>DEF</#if>";
String m1 = s1.replaceAll("(?<=if \\(|elseif )\\$\\{([^}]*)\\}([+-])\\$\\{([^}]*)\\}", "$1$2$3");
String m2 = m1.replaceAll("\\$\\{(f1[^)]*\\))\\}", "$1");
System.out.println(m2);

Output:

<#if (val1-val2) + f1(${a}+${b}*${c}) > 2000>ABC<#elseif n1+n2* f1(${n3}-${n4}) < 500>DEF</#if>

First replaceAll method removes ${} which was present just after to the if and elseif. And the second replaceAll method removes ${} symbols which was wrapping around f1.

IDEONE

Avinash Raj
  • 172,303
  • 28
  • 230
  • 274
  • I tried it with your expression and i m getting this output <#if (val1-val2) + ${f1(${a}+${b}*${c})} > 2000>ABC<#elseif n1+n2* ${f1(${n3}-${n4})} < 500>DEF#if> which is partially fine. I want to remove ${} wrapping the function f1 too – Naman Jul 18 '14 at 08:51