dousu8767
2015-11-05 10:42
浏览 276
已采纳

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

I need to extract a predefined set of hashtags from a blob of text, then extract what number follows right after it if any. Eg. I'd need to extract 30 from "Test string with #other30 hashtag". I assumed preg_match_all would be the right choice.

Some test code:

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

Output:

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

Perfect... Works as expected. Now to extract the number:

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

Output:

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

What? Looks like it's trying to match every character?

I'm aware of some preg_match_all related answers (one, two), but they all use a parenthesized subpattern. According to documentation - it is optional.

What am I missing? How do I simply get all matches into an array that match such a basic regex like /\d*/ There doesn't seem to be a more appropriate function in php for that.

I never thought I'd be scratching my head with such a basic thing in PHP. Much appreciated.

图片转代码服务由CSDN问答提供 功能建议

我需要从一串文本中提取一组预定义的主题标签,然后提取紧跟在其后面的数字,如果 任何。 例如。 我需要从“使用#other30 hashtag测试字符串”中提取30。 我假设preg_match_all是正确的选择。

一些测试代码:

  $ hashtag ='#other'; 
 $ string  ='使用#other30 hashtag测试字符串'; 
 $ matches = []; 
preg_match_all('/'。$ hashtag。'\ d * /',$ string,$ matches); 
print_r($ matches); \  n   
 
 

输出:

 数组
(
 [0] =>数组
(
  [0] => #other30 
)
)
   
 
 

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

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

输出:

 数组
(
 [0] =>数组
(
 [0] => 
 [1] =  > 
 [2] => 
 [3] => 
 [4] => 
 [5] => 
 [6] => 30 
 [7] =>  ; 
)
)
   
 
 

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

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

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

I 从来没有想过我会在PHP中用这样一个基本的东西挠挠脑袋。 非常感谢。

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

4条回答 默认 最新

  • douxuanou2787 2015-11-05 10:47
    已采纳

    You need to replace:

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

    with:

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

    Replace * with +

    Because

    * Match zero or more times.

    + Match one or more times.

    点赞 评论
  • dongnai3960 2015-11-05 10:45

    You can use a capturing group:

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

    Here (\d*) will capture the number after $hashtag.

    点赞 评论
  • dongpu2727 2015-11-05 10:51

    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];
    
    ?>
    
    点赞 评论
  • duanqian9503 2015-11-05 11:19

    Also see, that you can reset after a certain point to get part of a match by using \K. And of course need to use \d+ instead of \d* to match one or more digits. Else there would be matches in gaps in between the characters where zero or more digits matches.

    enter image description here

    So your code can be reduced to

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

    See the demo at eval.in and consider using preg_quote for $hashtag.

    点赞 评论

相关推荐 更多相似问题