我有一个文字,并尝试在其中添加每个3号码的链接
我使用带有模式的preg_match_all:(^|[^\d])(\d{3})($|[^\d])
此处使用分组仅将链接添加到数字,而不是添加到其邻居。
测试用例是:
a 123 234 b
- 必须匹配123和234 a 123_234 b
- 必须匹配123和234 aa123 234 b
- 必须匹配123和234 a0123 234 b
- 必须匹配 234 123a234 b
- 必须匹配123和234 a 123 234
- 必须匹配123和234 测试2和3工作正常,其他测试因两个数字之间的空间而失败 如何匹配两个数字之间只有1个空格?
答案 0 :(得分:4)
您可以通过使用正向前瞻 - api doc替换最后一个捕获组来“修复”您的正则表达式,以允许重叠匹配。 {3}组之后($|[^\d])
组消耗了空格,而第一个(^|[^\d])
无法与该空格匹配。如果您更喜欢这种方法,我会用[^\d]
替换\D
。
我建议使用负面外观,因为它看起来“更干净”:
(?<!\d)\d{3}(?!\d)
^^^^^^ ^^^^^^
请参阅(^|[^\d])(\d{3})(?=$|[^\d])
<强>详情:
(?<!\d)
- 当前位置不应以数字\d{3}
- 3位数(?!\d)
- 当前位置右侧必须没有数字。答案 1 :(得分:1)
这是我的两分钱:
\d{4,}(*SKIP)(*FAIL)|(\d{3})
正则表达式示例为here。
这意味着:
\d{4,}(*SKIP)(*FAIL) -> match 4 digits or more but skip the match
| -> Or
(\d{3}) -> match 3 digits and capture it.
这意味着您的正则表达式仅匹配捕获组中3位数的出现次数。
希望它有所帮助。
编辑:
添加了(*SKIP)(*FAIL)
个动词。
这两个动词允许您强制匹配失败。然后,可以完成替换。 (参见regex101示例的替换部分)。
在php中,代码如下所示:
$arr = array(
"a 123 234 b",
"a 123_234 b",
"aa123 234 b",
"a0123 234 b",
"123a234 b",
"a 123 234"
);
$regex = "/\d{4,}(*SKIP)(*FAIL)|(\d{3})/";
foreach ($arr as $item) {
echo preg_replace($regex, '<a href="#">$1</a>', $item);
echo "\r\n";
}
输出:
a <a href="#">123</a> <a href="#">234</a> b a <a href="#">123</a>_<a href="#">234</a> b aa<a href="#">123</a> <a href="#">234</a> b a0123 <a href="#">234</a> b <a href="#">123</a>a<a href="#">234</a> b a <a href="#">123</a> <a href="#">234</a>