为啥 preg_match_all 返回两个匹配项?

Posted

技术标签:

【中文标题】为啥 preg_match_all 返回两个匹配项?【英文标题】:Why is preg_match_all returning two matches?为什么 preg_match_all 返回两个匹配项? 【发布时间】:2014-12-23 18:03:07 【问题描述】:

我正在尝试使用preg_match_all 识别字符串是否在双引号之间有任何单词,但是它会重复结果,并且第一个结果的两边都有两组双引号,而正在搜索的字符串只有一组.

这是我的代码:

$str = 'Test start. "Test match this". Test end.';
$groups = array();
preg_match_all('/"([^"]+)"/', $str, $groups);
var_dump($groups);

var 转储产生:

array(2) 
    [0]=>
    array(1) 
        [0]=>
        string(17) ""Test match this""
    
    [1]=>
    array(1) 
        [0]=>
        string(15) "Test match this"
    

如您所见,第一个数组是错误的,为什么preg_match_all 会返回这个?

【问题讨论】:

省略括号,或添加一些括号,阅读手册,您会解决的 请定义错误。这与php.net/preg_match_all 给出的期望有何不符? 你没有定义错,也可能是你把var_dump的输出弄混了? 是的,我很困惑var_dump。我没有意识到preg_match_all 记录了有和没有捕获,并且它是var_dump 在字符串周围添加引号。这两个双引号是我认为是错误的 【参考方案1】:

它返回 2 个元素,因为:

元素 0 捕获整个匹配的字符串

元素1..N 捕获专用匹配项。

PS:另一种表达方式可能是

(?<=")[^"]+(?=")

这将捕获完全相同但在这种情况下您不需要额外的捕获组。

演示:http://regex101.com/r/lF3kP7/1

【讨论】:

这不会产生我期望的结果,它包含结束字符串 - eval.in/210849 @Styphon:提示:(?=") @Avinash Raj:var_dump 将所有字符串文字括在双引号中。不过,这不是问题的意义所在。 @Styphon:那么对不起。我习惯于认为有 100 多个答案的 OP 会首先检查文档。我错了:-D @Styphon:很公平(在我提出问题之前,我会尝试在多个输入上使用我不理解的功能。var_dump('foo') 会展示它的行为)【参考方案2】:

您好,如果您使用的是 print_r 而不是 vardump,您会以更好的方式看到差异。

Array
(
    [0] => Array
        (
            [0] => "Test match this"
        )

    [1] => Array
        (
            [0] => Test match this
        )

)

第一个包含整个字符串,第二个是你的匹配项。

【讨论】:

对,没有意识到 preg_match_all 两个都返回了,谢谢。【参考方案3】:

去掉括号。 你可以把模式写成'/"[^"]+"/'

【讨论】:

【参考方案4】:

这是因为您使用的是组匹配。把括号从你的模式中去掉,你会得到一个数组。比如:

preg_match_all('/\"[^"]+\"/', $str, $groups);

【讨论】:

你为什么要转义引号?

以上是关于为啥 preg_match_all 返回两个匹配项?的主要内容,如果未能解决你的问题,请参考以下文章

突出显示 preg_match_all() 的主题字符串中的匹配结果

preg_match_all JS 等效?

使用 preg_match_all PHP 限制结果数

如何编写从两个搜索值返回匹配项的 sql 查询

如何映射两个数组并将匹配项作为按钮返回?

如何比较python中的两个列表并返回匹配项