function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Mthobisi NdlovuMthobisi Ndlovu 

Need help with Regex on Apex, the whole string gets replaced instead of a specific string

I am having issues with Regex on apex.

I am trying to have a method to dynamically replace place holders in a string, example of placeholder : [COW_NAME] and an example of string(message) :
"Cow [COW_NAME] Signs of heat: Check cows vulva for clear discharge and change of colour of vulva lips from pink to red. Check every day of heat week."

My first issue was that even if I found a match instead of having the placeholder replaced by a cow name, the whole string would get replaced.

the first Regex: \\b.*[COW_NAME]\\b.* , match is found but the whole string is replaced
the second rege: \\[COW_NAME\\] didn't work no match was found at all.
I have only used Regex on Javascript a few times but  we all know JScript is different from Java.

public String replacePromptPlaceholder(ServiceData serviceData) {		
 String livestockValue;
 String replacedMessage = serviceData.message;
		
 if (serviceData.hasAPromptThatRequiresSubstitution()) {
	String message = serviceData.message;
	List<Template_Matcher__c> promptTemplateMatcherList = getPromptTemplateMatchers();
	if (promptTemplateMatcherList != null) {
	   for (Template_Matcher__c promptTemplate : promptTemplateMatcherList) {
		Pattern regexPattern = Pattern.compile(promptTemplate.Prompt_Regex__c);
		Matcher regexMatcher = regexPattern.matcher(message);
		if (regexMatcher.matches() == true) {
	        livestockValue = getLivestockPlaceholderValue(promptTemplate, serviceData.livestock);
	replacedMessage = message.replaceAll(promptTemplate.Prompt_Regex__c, livestockValue);
		    }
		}
	   }
	}
	return replacedMessage;
}

private static String getLivestockPlaceholderValue(Template_Matcher__c template, Livestock__c livestock ) {
 String livestockFieldValue = null;
 Object value = livestock.get(template.Field_Name__c);
 if (value != null) {
    livestockFieldValue =  String.valueOf(value);
	}
  return livestockFieldValue;
}

I am not sure if my code is wrong or it's my regex. Please assist
Best Answer chosen by Mthobisi Ndlovu
pconpcon
The problem was a combination of your regex and the fact that you were using matches() instead of find()

String message = 'Your Cow [COW_NAME]  Has signs of heat: Check cows vulva for clear discharge';
String regex = '\\[COW_NAME\\]';
Pattern regexPattern = Pattern.compile(regex);
Matcher regexMatcher = regexPattern.matcher(message);

String replacedMessage;

if(regexMatcher.find()) {
   replacedMessage = message.replaceAll(regex, 'Alfred');
}

System.debug(System.LoggingLevel.ERROR, replacedMessage);

This code returns the expected string

All Answers

pconpcon
I believe your regex is wrong.  The reason the \\ was there is to escape the \b.  Can you please include just a simplified apex that shows what the regex is doing like:

String message = 'my string';
Pattern regexPattern = Patter.compile('mypattern');
Matcher regexMatcher = regexPattern.matcher(message);
String result = message.replaceAll('mypattern', 'replacement');

So we can take this code and run it in the developer console?


Mthobisi NdlovuMthobisi Ndlovu
Hi Pcon

I'm not sure if this is what you want, but let me know if it's not.

String message = 'Your Cow [COW_NAME]  Has signs of heat: Check cows vulva for clear discharge';
String regex = '\\b.*[COW_NAME]\\b.*';
Pattern regexPattern = Patter.compile(regex);
Matcher regexMatcher = regexPattern.matcher(message);
if(regexMatcher.matches() == true) {
   String replacedMessage = message.replaceAll(regex, 'Alfred');
}

Expected String Result: Your Cow Alfred  Has signs of heat: Check cows vulva for clear discharge
pconpcon
The problem was a combination of your regex and the fact that you were using matches() instead of find()

String message = 'Your Cow [COW_NAME]  Has signs of heat: Check cows vulva for clear discharge';
String regex = '\\[COW_NAME\\]';
Pattern regexPattern = Pattern.compile(regex);
Matcher regexMatcher = regexPattern.matcher(message);

String replacedMessage;

if(regexMatcher.find()) {
   replacedMessage = message.replaceAll(regex, 'Alfred');
}

System.debug(System.LoggingLevel.ERROR, replacedMessage);

This code returns the expected string
This was selected as the best answer
pconpcon
This escapes the [ and the ] (reserved characters in regex).  The find() then sees if the regex exists somewhere in the string.  matches() requires that the entire regex matches the message string
Mthobisi NdlovuMthobisi Ndlovu
Thanks a lot Pcon,  I had initially used

String regex = '\\[COW_NAME\\]';
 but I guess i using the wrong method (matches()), I stii have a long way to go when it comes to regex.