Reputation: 1521
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
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
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