Hommer Smith
Hommer Smith

Reputation: 27852

Preg replace with array of patterns not working as expected

Why would this code

 $my_replacements = array("my dog", "doga");
 $my_string = "doga my dog test";
 $my_patterns = array_map(function($my_text) { return "/(^|[\n\r\f\t \.\,])" . trim($my_text) . "([\n\r\f\t \.\,]|$)/iu"; }, $my_replacements);
 $replaced_string = preg_replace($my_patterns, '', $my_string);
 echo $replaced_string;

return dogatest instead of test?

but if my_string is changed to "my dog doga test", it replaces correctly both elements in my_replacements?

What I want to accomplish is that, given a string, find all the strings that are in $my_replacements and delete them from the string. Taking into account the /u modifier and /i modifier or a preg_replace, because it can happen that the substring is in uppercase, and it has to be deleted either way.

Upvotes: 1

Views: 102

Answers (2)

vectorialpx
vectorialpx

Reputation: 586

Is there a reason of why you don't use str_replace? If yes, you can use
$my_replacements = array("doga", "my dog");
instead of
$my_replacements = array("my dog", "doga");

Reason: after "doga" is replaced with '' in your string, this becomes "dogatest". So, doga with spaces (as you defined the regular exp) is not there. You could also make the replace with " " instead of '',
$replaced_string = preg_replace($my_patterns, ' ', $my_string);
And then trim and replace all multiple spaces with one space (a simple recursive replace).

Upvotes: 1

zerkms
zerkms

Reputation: 255015

Because your replacements are transformed to the following regexps:

/(^|[\n\r\f\t \.\,])my dog([\n\r\f\t \.\,]|$)/iu
/(^|[\n\r\f\t \.\,])doga([\n\r\f\t \.\,]|$)/iu

After the first regex is applied to the source string "my dog doga test" - it cuts off the dog doga with spaces around it. So you get dogatest.

And after that the second regex cannot match anything, because it expects the doga to be enclosed by beginning or the end of the string, a space or punctuation. But in your case it's in the beginning of the string (true) but there is no a space, punctuation or end of the string after (false).

That's why the second regex doesn't modify the string and you get dogatest as a final result.

Straightforward solution without regexes:

 $my_replacements = array("my dog", "doga");
 $my_string = "doga my dog test";
 $replaced_string = str_replace($my_replacements, '', $my_string);
 echo $replaced_string;

The kind @Asad created a codepad demo of the script: http://codepad.org/ywbZR1i8

Upvotes: 2

Related Questions