Tom Folk Tom Folk - 2 years ago 76
PHP Question

Regex match overlap/crossover

I need to capitalise acronyms in some text.

I currently have this regex to match on the acronyms:


Explanation: this is aiming to match any of the acronyms where they are either at the start or end of the text, or there isn't a letter or number either side of them (as then they might be part of a word - e.g. I wouldn't want to replace the "Esc" in the word "Escape").

This works most of the time, but doesn't work for the following example:


It matches the
, but not the
. I'm guessing this is because the matches overlap, in that the forward slash is part of the match relating to

Can anyone suggest how to get a match on both?

As a side note, I'm using PHPs preg_replace_callback to perform the transformation afterwards:

$name = 'abs/esc';
$name = preg_replace_callback('/(^|[^a-z0-9])('ECU|HVAC|ABS|ESC|EGR|ADAS|HEV|HMI')($|[^a-z0-9])/i', function($matches) {
return $matches[1] . strtoupper($matches[2]) . $matches[3];
}, $name);

Answer Source

Yes the reason is because it overlaps (when matching the abs, it also consumes the /. Then for esc, it cannot find [^a-z0-9] because the next letter it is scanning is e).

You could use this RegEx instead:


\b is a Word Boundary, it does not consume any characters and therefore there will be no overlap

Live Demo on Regex101

You can also change your RegEx to use a Positive Lookahead, since this also does not consume characters:


Live Demo on Regex101

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download