2

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

1

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.

2

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)

1
  • 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 .