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

我有一个文本,并尝试将链接添加到其中的每个大小为 3 的数字。
我将 preg_match_all 与一个模式一起使用:(^|[^\d])(\d{3})($|[^\d])
此处使用分组来仅将链接添加到数字,而不是添加到它们的邻居。 测试用例是:

  1. a 123 234 b - 必须匹配 123 和 234
  2. a 123_234 b - 必须匹配 123 和 234
  3. aa123 234 b - 必须匹配 123 和 234
  4. a0123 234 b - 必须匹配 234
  5. 123a234 b - 必须匹配 123 和 234
  6. a 123 234 - 必须匹配 123 和 234

测试 2 和 3 工作正常,其他测试因 2 个数字之间的空格而失败。
如何匹配两个数字之间只有 1 个空格?

【问题讨论】:

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

标签: php regex preg-match-all


【解决方案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>

【讨论】:

    【解决方案2】:

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

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

    (?<!\d)\d{3}(?!\d)
    ^^^^^^      ^^^^^^
    

    regex demo

    详情

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

    【讨论】:

    • 如果您需要替换 preg_replace 中的匹配项,请使用 $0 反向引用替换整个匹配项。
    • 非常感谢!你的建议更清晰,更容易理解。
    猜你喜欢
    • 1970-01-01
    • 2016-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-17
    • 2014-02-06
    • 1970-01-01
    • 2012-07-05
    相关资源
    最近更新 更多