preg_offset_capture子数组*保证*的顺序是否增加偏移量?

时间:2014-06-12 17:37:50

标签: php arrays regex

我还没有找到一个权威的答案,虽然我99.9%肯定这是真的。接受answer接受它的事情是正确的,因为我期待很多其他代码。但真正了解preg_match_all的人(不是通过观察,而是通过指定的要求或指定的算法)可以确认这是保证行为吗?我无法从文档中收集它。

我的用例非常简单:

preg_match_all("/$regexp/", $content, $matches, PREG_OFFSET_CAPTURE);

我知道$regexp不包含任何子模式,因此文档告诉我$matches[0]将是一个2元素数组的数组,其中每个子数组都包含带数字的元素key 0包含与模式匹配的字符串,数字键1包含发生匹配的$content偏移量。虽然通过增加偏移来排序数组元素似乎是合理的,但我不知道需要哪些地方,如果不是这样的话就会出现错误。虽然我无法想象它是如何实现有用的效果的,但也许有一些方法可以实现preg_match_all多个线程附加其部分结果而不会合并为完全排序的顺序。

在我的特定情况下,我只关心偏移,而不是匹配的字符串,但偏移量增加至关重要。因此,我使用腰带和吊带心态编码:

preg_match_all("/$regexp/", $content, $matches, PREG_OFFSET_CAPTURE);
$offsets = array();
foreach ($matches as $match) {
    $offsets[] = $match[1];
}
sort($offsets);

换句话说,最终sort($offsets)是否有保证会浪费周期?

如果它因为询问相关但可能独立的问题而无法让我陷入困境,如果排序可能有用,那么采用默认SORT_REGULAR会更多/更少/同样有效吗?如果显示标记,或明确指定SORT_NUMERIC,假设preg_match_all中产生的偏移量必须是数字?

1 个答案:

答案 0 :(得分:6)

关于字符串偏移顺序的问题:

完全匹配应始终采用升序字符串偏移顺序。 PHP使用设置start_offset的循环实现全局匹配 在最近的完整匹配结束时,直到主题字符串结束。也就是说,它找到第一个匹配,然后是第二个匹配 第三,等等。

如果您想验证我是不是误读了源代码(或遗漏了一些重要内容),您可以查看该功能 php_pcre_match_impl中的ext/pcre/php_pcre.cpreg_match_all将全局参数设置为1.最后让我了解的是最后的评论 global的do while循环:

/*Advance to the position right after the last full match*/
start_offset = offsets[1];

如果设置了global,则循环将以新偏移重复,并再次使用它调用pcre_exec

关于您的SORT_NUMERIC问题:

很难说。设置SORT_NUMERIC会排序使用numeric_compare_function进行元素比较,其中SORT_REGULAR使用compare_function

compare_function进行类型检查,然后决定从那里做什么比较,而numeric_compare_function只是盲目地将两者转换为 double秒。两者都是LONG compare_function,只需比较它们而不进行任何转换。所以它最终将取决于哪个更快:盲目地转换为double,或执行类型检查。