PHP preg_match返回错误的索引

时间:2013-08-26 07:03:02

标签: php regex

我正在尝试使用PHP的preg_match从字符串中提取特定单词的所有索引。例如,单词hello

$r = "/\b(hello)\b/u";

假设我想在这个字符串中查找它:

$s = 'hello. how are you, hello there. helloorona!';

如果我使用preg_match参数运行PREG_OFFSET_CAPTURE并传入一个名为$ matches的数组,

preg_match($r, $s, $matches, PREG_OFFSET_CAPTURE);

我希望能够返回这样的内容(即忽略最后一个“hellooroona”短语):

["hello", 0], ["hello", 20]

但事实上,当我通过$matches或通过循环遍历所有匹配来返回json_encode的值时,返回的值始终为:

["hello", 0], ["hello", 0]

如果我在类似的字符串上运行,请说

$s = 'how are you, hello there.';

答案是

["hello", 13]

这是正确的。在hello hello hello上运行它,我得到三个索引,全部为0.

摘要

所以看起来索引计数器只是总是返回第一个索引。这是预期的行为吗?我如何获得实际索引?

2 个答案:

答案 0 :(得分:2)

preg_match匹配第一个匹配,然后停止。结果数组始终在其0索引中包含完整匹配表达式,并且在1开始的以下索引中包含所有捕获组。 E.g:

preg_match('/foo (\w+)/', 'foo bar', $r)

$r此处包含0 => 'foo bar', 1 => 'bar'

所以在你的情况下,由于这个原因,你只看到了第一次hello

如果要匹配所有出现的表达式,请使用preg_match_all

答案 1 :(得分:1)

第二个["hello", 0]不是字符串中的第二个问候语,而是子组的匹配。

使用preg_match_all,它会为您提供预期的结果:

// note: sub group is not necessary
$r = "/\bhello\b/u";
$s = 'hello. how are you, hello there. helloorona!';
preg_match_all($r, $s, $matches, PREG_OFFSET_CAPTURE);