如何匹配包含特殊字符的正则表达式模式?

时间:2015-10-14 15:10:17

标签: php regex

我有一个通用例程,用于替换具有性别特定选项的短代码(以" ^"字符开头)。我被要求延长这个以纠正一些常见的拼写错误。这些词在开始时不会有特殊的性格。

到目前为止,我一直在使用PHP的str_replace函数,但由于某些单词出现在其他单词中的可能性,我需要确保代码在匹配时使用单词边界。我现在正在尝试使用preg_replace

虽然实际代码是从数据库表中获取数据,包括性别特定的替换,但我可以用更简单的代码重现问题,以便提出这个问题。

考虑以下具有$search => $replace结构的数组:

$subs = array("^Heshe" => "He",
   "apples" => "bananas");

然后我想循环遍历数组以替换标记:

$message = "^Heshe likes apples but not crabapples.";
foreach ($subs as $search => $replace)
{
   $pattern = '/\b' . preg_quote($search, '/') . '\b/u';
   $message = preg_replace($pattern, $replace, $message);
}
echo $message;

我希望显示消息He likes bananas but not crabapples.,但我收到消息^Heshe likes bananas but not crabapples.

我也试过了$pattern = '/\b\Q' . $search . '\E\b/u',也有同样的结果。

不幸的是," ^"字符是某些遗留系统的一部分,更改它是不可行的。如何让正则表达式工作?

1 个答案:

答案 0 :(得分:2)

问题在于这一行:

$pattern = '/\b' . preg_quote($search, '/') . '\b/u';

由于$search^Heshe,您无法在\b之前匹配^(字边界),因为这不是单词字符。

您可以在模式中使用lookarounds,如下所示:

$pattern = '/(?<!\w)' . preg_quote($search, '/') . '(?!\w)/u';

这意味着匹配$search如果没有跟随并且前面有单词char。

或者使用:

$pattern = '/(?<=\s|^)' . preg_quote($search, '/') . '(?=\s|$)/u';

如果跟随并且前面有空格或行开头/结尾,则表示匹配$search