使用 preg_match_all 将所有数字与正则表达式匹配

Posted

技术标签:

【中文标题】使用 preg_match_all 将所有数字与正则表达式匹配【英文标题】:Matching all numbers with regex using preg_match_all 【发布时间】:2017-06-25 00:57:18 【问题描述】:

我有一个文本,并尝试将链接添加到其中的每个大小为 3 的数字。 我将 preg_match_all 与一个模式一起使用:(^|[^\d])(\d3)($|[^\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 工作正常,其他测试因 2 个数字之间的空格而失败。 如何匹配两个数字之间只有 1 个空格?

【问题讨论】:

另外,您可以“修复”您的正则表达式,只需将最后一个捕获组替换为正向前瞻(^|[^\d])(\d3)(?=$|[^\d]),以允许重叠匹配。我建议使用环视,因为这样看起来“更干净”。见regex101.com/r/27pWL2/1。 Surley,如果您更喜欢这种方法,我会将 [^\d] 替换为 \D 【参考方案1】:

这是我的两分钱:

\d4,(*SKIP)(*FAIL)|(\d3)

正则表达式示例是here。

意思是:

\d4,(*SKIP)(*FAIL)  -> match 4 digits or more but skip the match
|                     -> Or
(\d3)               -> 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 = "/\d4,(*SKIP)(*FAIL)|(\d3)/";

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>

【讨论】:

【参考方案2】:

您可以“修复”您的正则表达式,只需将最后一个捕获组替换为 正向预测 - (^|[^\d])(\d3)(?=$|[^\d]) - 以允许重叠匹配。 ($|[^\d]) 组消耗了 3 位块之后的空间,第一个 (^|[^\d]) 无法匹配该空间。 Surley,如果您更喜欢这种方法,我会将[^\d] 替换为\D

我建议使用负面的环视,因为这样看起来“更干净”:

(?<!\d)\d3(?!\d)
^^^^^^      ^^^^^^

见regex demo

详情

(?&lt;!\d) - 当前位置不应以数字开头 \d3 - 3 位数 (?!\d) - 当前位置右侧不能有数字。

【讨论】:

如果您需要替换 preg_replace 中的匹配项,请使用 $0 反向引用替换整个匹配项。 非常感谢!你的建议更清晰,更容易理解。

以上是关于使用 preg_match_all 将所有数字与正则表达式匹配的主要内容,如果未能解决你的问题,请参考以下文章

preg_match_all JS 等效?

Preg_match_all 在数组中返回数组?

使用 preg_match_all() 获取重复匹配

PHP - preg_match_all 没有搜索完整的字符串?

数字, 汉字 , 字符 ,混合截取

多个通配符 preg_match_all php