正则表达式使电话号码变粗 - 不能始终有效

时间:2016-04-29 14:05:22

标签: php regex preg-replace

我需要在字符串中的任何电话号码周围包裹粗体标签。我有以下正则表达式

/(\d[\d\s]*)(?=\s+)/

适用于此:

  

立即致电0800 2458 452!

但不是这样:

  

立即致电0800 2458 452

因此,如果数字出现在字符串的末尾,则正则表达式无法正常工作。它输出的字符串错过了最后三位数字的粗体。

Call us now on <b>0800 2458</b> 452

任何人都可以看到代码有什么问题吗?

$bold_text = preg_replace('/(\d[\d\s]*)(?=\s+)/', '<b>$1</b>', $text);

2 个答案:

答案 0 :(得分:2)

使用单词边界而不是空格

(\d[\d\s]*)(?=\b)

最好在

之前添加相同内容
(?<=\b)(\d[\d\s]*)(?=\b)

不要与B52匹配

答案 1 :(得分:1)

您的超前模式要求在电话号码后面至少显示1个空格。您可以“展开”您的模式以匹配单词边界:

\b\d+(?:\s+\d+)*\b

请参阅regex demo

或使用明确的字边界 - (?<!\w)(?!\w)

(?<!\w)\d+(?:\s+\d+)*(?!\w)

模式匹配:

  • (?<!\w) - 数字
  • 前没有字符
  • \d+ - 1+位数
  • (?:\s+\d+)* - 1个以上空格的零个或多个序列,后跟1个数字
  • (?!\w) - 未跟随字(字母数字/下划线)字符。

请参阅this regex demo

IDEONE PHP demo

$re = '~(?<!\S)\d+(?:\s+\d+)*(?!\S)~'; 
$strs = array("Call us on 0800 2458 452 now!","Call us now on 0800 2458 452"); 
foreach ($strs as $str) {
 echo preg_replace($re, '<b>$0</b>', $str) . PHP_EOL;
}

GOTCHA:FLOAT NUMBERS

如果要确保浮点数与正则表达式不匹配,请使用

(?<!\w|\d\.)\d+(?:\s+\d+)*(?!\w|\.\d)

请参阅regex demo