【问题标题】:Capture two numbers in a string with PHP preg_match使用 PHP preg_match 捕获字符串中的两个数字
【发布时间】:2014-02-28 00:43:37
【问题描述】:

这是一段非常简单的代码:

<?php
 $matches = array();
 $str = "You came in 21st out of 53";
 preg_match("/(\d+).*(\d+)/",$str,$matches);
 echo var_dump($matches);
 ?>

我正在学习和试验 PHP 的 preg_match 和正则表达式。我以为上面的代码会捕获“21”和“53”,但它实际捕获的是“21”和“3”。

这里是 echo var_dump($matches); 的结果

array(3) { 
          [0]=> string(14) "21st out of 53" 
          [1]=> string(2) "21" 
          [2]=> string(1) "3" 
         } 
  1. 如何编写正则表达式来捕获“53”?我希望答案足够笼统,它还可以捕获“153”和“jkj53hjjk”(这样表达式就不会更改为“/(\d+).*(\b\d+)/”。

  2. 如果可以讨论,为什么在捕获第一个数字时,它会如此贪婪,而在捕获第二个数字时,它却不贪婪?它是否向后捕获数字,因此很高兴在找到的第一个数字处停下来?这可以克服吗?

这是我在 Stack Overflow 上的第一篇文章。我对这个问题进行了相当多的研究,但找不到答案。

【问题讨论】:

    标签: php regex preg-match


    【解决方案1】:

    问题是你的 .* 是贪婪的,并且在正则表达式需要匹配第二个 \d+ 之前尽可能多地抓取字符才能解决。添加一个?应该让它按预期工作:

    (\d+).*?(\d+)
    

    【讨论】:

    • 谢谢。我测试了这个答案,它确实有效。推理完全有道理。
    • 另外,在贪心量词之后添加问号会强制匹配器在贪心量词之前的子表达式的每次匹配中检查下一个表达式是否也匹配。
    【解决方案2】:

    这很正常,根据文档设计:http://php.net/preg_match

    If matches is provided, then it is filled with the results of search. $matches[0] will contain the text that matched the full pattern, $matches[1] will have the text that matched the first captured parenthesized subpattern, and so on.

    如果您不想要完整的匹配字符串,那么只需将 array_shift()$matches 数组中取出。

    【讨论】:

      【解决方案3】:

      /(\d+)[^0-9]+(\d+)/

      添加没有任何范围以匹配 53 也

      /(\d+)[^0-9]+ (.*\d+.*)/

      添加空格并用.*包围\d以匹配sfgdfg53gfdg

      【讨论】:

      • 谢谢。即使使用 sfgdfg53gfdg,您也可以完美地提供第一个正则表达式。它拉出“53”作为第二个匹配项。
      • 还没测试(电话回复)
      • 好的。现在标记最佳答案并投票给其他正确的答案。 ;) 顺便说一句,今天在正则表达式 stackoverflow.com/questions/22045784/php-code-to-split-the-url/… 上检查我之前的答案
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多