I have a string (1 and 2) Or (3 and 4) the format of the () can be changed because it is auto generated in the filter of the reports. and i do have four conditions that

1) Age = '60'

2) FirstName = 'a'

3) lastname = 'b'

4) stage = 'open'.

Here in my scenario I am replacing the the 1st with the age, 2nd with firstname etc. As the value of the age is 60 then there is no problem because 6 does't exist in the (1 and 2) Or (3 and 4) format so I am able to get the proper format and its work properly. But when the value of age is changed to a value like 30 or any number which exists in the format it replaces the the 3 in the new age value also, so the output would be:

(b0 and a) Or (b and open)

I am bit confused how to overcome this situation. please help me out how it is possible for us to get the fix this issue.

2 Answers 2


This isn't 100% foolproof depending on the user input, but by doing an initial replacement on the keys with values that won't exsist in the replacement data you can make the problem a lot easier:

String input = '(1 and 2) or (3 and 4)';

Map<String, String> valueMap = new Map<String, String>
    '1' => '30',
    '2' => 'Bob',
    '3' => '40',
    '4' => 'Smith'

for(String key : valueMap.keySet())
    input = input.replace(key, '-=' + key + '=-');

for(String key : valueMap.keySet())
    input = input.replace('-=' + key + '=-', valueMap.get(key));

So in this case, I'm replacing the keys in the input so it would look like:

'(-=1=- and -=2=-) or (-=3=- and -=4=-)';

Then you can replace those new keys with the values as before, hopefully knowing that a string such as -=1=- will never appear in the replacement data. Probably wouldn't hurt to throw in some more characters to ensure you're unlikely to get a collision. I'm sure there's more than a few ways to achieve the result you want, probably involving storing positions and using regex, but sometimes simple is the best option.


You may be able to leverage the String.format() method to do parameter substitution rather than using the String.replace() method and hoping for the best. Parameter substitution should be a much safer mechanism for this task.

The formatter call would look something like this (in keeping with your original pattern):

String.format('({1} and {2}) Or ({3} and {4})', new List<String>{ '','60', 'a', 'b', 'open'});

Note that the merge fields in the pattern are the index values in the array/list of strings parameter that are used for substitution. This is the reason that I have added an empty string at index 0 in the list. {0} isn't used in the pattern.

Here is a more complete, functional example:

// the starting pattern to be used for substitution
string sourcePattern = '(1 and 2) or (3 and 4)';
system.debug('sourcePattern: ' + sourcePattern);

// use regex to capture the numbers in the string and surround each with {n}
string tokenizedPattern = sourcePattern.replaceAll('([0-9]+)', '{$1}');
system.debug('tokenizedPattern: ' + tokenizedPattern);

// create the list of items for substitution
List<String> params = new List<String>{'', '60', 'a', 'b', 'open'};

// use the format method to replace the placeholders with their respective parameters
String mergedPattern = String.format(tokenizedPattern, params);
system.debug('mergedPattern: ' + mergedPattern);

DEBUG|sourcePattern: (1 and 2) or (3 and 4)

DEBUG|tokenizedPattern: ({1} and {2}) or ({3} and {4})

DEBUG|mergedPattern: (60 and a) or (b and open)

  • I knew there was somethinig obvious I was missing! Nice one Mark :)
    – Matt Lacey
    Aug 28, 2014 at 23:59

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .