php preg_match_all简单正则表达式返回空值

时间:2015-11-05 10:42:09

标签: php regex

我需要从一串文本中提取一组预定义的主题标签,然后提取紧跟在它后面的数字(如果有的话)。例如。我需要从“使用#other30 hashtag测试字符串”中提取30。我认为preg_match_all将是正确的选择。

一些测试代码:

$hashtag = '#other';
$string  = 'Test string with #other30 hashtag';
$matches = [];
preg_match_all('/' . $hashtag . '\d*/', $string, $matches);
print_r($matches);

输出:

Array
(
    [0] => Array
        (
            [0] => #other30
        )
)

完美......按预期工作。现在提取数字:

$string = $matches[0][0]; // #other30
$matches = [];
preg_match_all('/\d*/', $string, $matches);
print_r($matches);

输出:

Array
(
    [0] => Array
        (
            [0] =>
            [1] =>
            [2] =>
            [3] =>
            [4] =>
            [5] =>
            [6] => 30
            [7] =>
        )
)

什么?看起来它试图匹配每个角色?

我知道一些preg_match_all相关的答案(onetwo),但它们都使用带括号的子模式。根据文档 - 它是可选的。

我错过了什么?我如何简单地将所有匹配项放入一个匹配像/ \ d *这样的基本正则表达式的数组中。在php中似乎没有更合适的函数。

我从未想过我会在PHP中使用这样一个基本的东西。非常感谢。

4 个答案:

答案 0 :(得分:2)

您需要替换:

preg_match_all('/\d*/', $string, $matches);

使用:

preg_match_all('/\d+/', $string, $matches);

*替换为+

由于

  

*匹配零次或多次。

     

+匹配一次或多次。

答案 1 :(得分:1)

您可以使用捕获组:

preg_match_all('/' . $hashtag . '(\d*)/', $string, $matches); 
echo $matches[1][0] . "\n";
//=> 30

此处(\d*)将捕获$hashtag之后的数字。

答案 2 :(得分:1)

另请注意,您可以reset after a certain point使用\K参加比赛。当然,需要使用\d+代替\d*来匹配一个或多个数字。否则,在where zero or more digits matches字符之间的间隙中会有匹配。

enter image description here

因此您的代码可以缩减为

$hashtag = '#other';
$string  = 'Test string with #other30 #other31 hashtag';
preg_match_all('/' . $hashtag . '\K\d+/', $string, $matches);
print_r($matches[0]);

请参阅demo at eval.in并考虑将preg_quote用于$hashtag

答案 3 :(得分:0)

PHP Fiddle

<?php

    $hashtag = '#other';
    $string  = 'Test string with #other30 hashtag';
    $matches = [];
    preg_match_all('/' . $hashtag . '\d*/', $string, $matches);
    $string = preg_match_all('#\d+#', $matches[0][0], $m);
    echo $m[0][0];

?>