Perocat
Perocat

Reputation: 1521

preg_replace to match all match in string even after first replace

This outputs:

$san_field = 'sometext PROS sometext sometext1234 CALEND 2007 RIT';
$pattern = '/(\s|^|- |--)(?:CALEND|2007|CALEND 2007 RIT)(--| -|\s|$)/i';
echo preg_replace($pattern, ' ', $san_field)

>> sometext PROS sometext sometext1234 2007 RIT

I'd like to replace CALEND 2007 RIT instead of CALEND which is the first match found on $san_field. I know I can do this way:

$san_field = 'sometext PROS sometext sometext1234 CALEND 2007 RIT';
$pattern = '/(\s|^|- |--)(?:CALEND 2007 RIT|CALEND|2007)(--| -|\s|$)/i';
echo preg_replace($pattern, ' ', $san_field)

>> sometext PROS sometext sometext1234

but is there a more correct and practical way, because I will insert those pattern into an array which will be quite large...

Upvotes: 3

Views: 338

Answers (2)

Sherif
Sherif

Reputation: 11943

What you're looking for is called a negative look ahead assertion in PCRE (or check out the PCRE cheat sheet for easier reading), which tells the engine to look for something like 'CALEND' as long as it's not followed directly by ' 2007 RIT', in your case.

$san_field = 'sometext PROS sometext sometext1234 CALEND 2007 RIT';
$pattern = '/(\s|^|- |--)(CALEND(?! 2007 RIT)|2007|CALEND 2007 RIT)(--| -|\s|$)/i'
echo preg_replace($pattern, ' ', $san_field)

Which gives you...

sometext PROS sometext sometext1234

Upvotes: 2

Martin.
Martin.

Reputation: 10529

How about putting these patterns to an array, sorting that array by length (so longer text is checked first) and build up your regex afterwards?

$replace = ["2007", "CALEND", "CALEND 2007 RIT"];
usort($replace, function($a, $b){
    return strlen($b) - strlen($a);
});
$san_field = 'sometext PROS sometext sometext1234 CALEND 2007 RIT';
$pattern = '/(\s|^|- |--)(?:'.(implode('|', $replace)).')(--| -|\s|$)/i';
echo preg_replace($pattern, ' ', $san_field)

Additionally, it would be a good idea to preg_quote these values, just in case you put some special characters in.

foreach($replace as &$item) {
    $item = preg_quote($item);
}

Upvotes: 2

Related Questions