正则表达式匹配重叠/交叉

时间:2016-04-22 07:23:00

标签: php regex

我需要在某些文字中大写首字母缩略词。

我目前有这个正则表达式匹配缩写:

/(^|[^a-z0-9])(ECU|HVAC|ABS|ESC|EGR|ADAS|HEV|HMI)($|[^a-z0-9])/ig

说明:这是为了匹配文本开头或结尾处的任何首字母缩略词,或者它们两边都没有字母或数字(因为它们可能是一部分的一部分)单词 - 例如,我不想在单词" Escape")中替换" Esc"。

这在大多数情况下都适用,但对以下示例不起作用:

"abs/esc"

它匹配abs,但不匹配esc。我猜这是因为匹配重叠,因为正斜杠是与abs相关的匹配的一部分。

有人可以建议如何在两者上得到匹配吗?

作为旁注,我之后使用PHP preg_replace_callback来执行转换:

$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);

1 个答案:

答案 0 :(得分:3)

是的,原因是它重叠(当匹配abs时,它也会消耗/。然后对于esc,它找不到[^a-z0-9],因为下一个字母扫描是e)。

您可以改用此RegEx:

\b(ECU|HVAC|ABS|ESC|EGR|ADAS|HEV|HMI)\b

\bWord Boundary,它不消耗任何字符,因此不会重叠

Live Demo on Regex101

您还可以将RegEx更改为使用正向前瞻,因为这也不会消耗字符:

(^|[^a-z0-9])(ECU|HVAC|ABS|ESC|EGR|ADAS|HEV|HMI)(?=$|[^a-z0-9])

Live Demo on Regex101