PHP的preg_Match()返回最后一场比赛的位置 [英] PHP's preg_match() returns the position of the last match

查看:0
本文介绍了PHP的preg_Match()返回最后一场比赛的位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

preg_match($pattern, $subject, $matches, PREG_OFFSET_CAPTURE);

是否可以反向搜索字符串?即返回该模式在主题中最后一次出现的位置,类似于strripos

还是必须用preg_match_all返回所有匹配项的位置并使用$matches的最后一个元素?

推荐答案

php没有从右向左搜索字符串的正则表达式方法(如.NET所示)。有几个可能的方法可以解决这个问题(这个列表不是详尽的,但它可能为您自己的解决方法提供一些想法):

  • 使用preg_match_allPREG_SET_ORDER标志和end($matches)将得到最后一个匹配集
  • 使用strrev反转字符串并构建要与preg_Match一起使用的反转模式
  • 使用preg_match并构建一个锚定在字符串末尾的模式,以确保在字符串末尾之前不再出现搜索到的掩码
  • 在目标之前使用贪婪的量词,K在您想要的位置开始匹配结果。到达字符串末尾后,正则表达式引擎将回溯,直到找到匹配项。

模式/x[A-Z]+d/的字符串$str = 'xxABC1xxxABC2xx'的示例

方法1查找所有匹配项并显示最后一个匹配项。

if ( preg_match_all('/x[A-Z]+d/', $str, $matches, PREG_SET_ORDER) )
    print_r(end($matches)[0]);

Demo

方法2查找颠倒的字符串与颠倒的模式的第一个匹配,并显示颠倒的结果。

if ( preg_match('/d[A-Z]+x/', strrev($str), $match) )
    print_r(strrev($match[0]));

Demo

请注意,反转模式并不总是那么容易。

方法3从x跳到x,并检查字符串末尾是否没有其他x[A-Z]+d匹配项。

if ( preg_match('/x[A-Z]+d(?!.*x[A-Z]+d)/', $str, $match) )
    print_r($match[0]);

Demo

变体

使用懒惰的量词

if ( preg_match('/x[A-Z]+d(?!.*?x[A-Z]+d)/', $str, $match) )
    print_r($match[0]);

或使用";缓和的量词

if ( preg_match('/x[A-Z]+d(?=(?:(?!x[A-Z]+d).)*$)/', $str, $match) )
    print_r($match[0]);

当您事先知道哪些地方最有可能发生匹配时,在这些变体之间进行选择可能会很有趣。

方法4转到字符串末尾并回溯,直到找到x[A-Z]+d匹配。K从匹配结果中删除字符串的开头。

if ( preg_match('/^.*Kx[A-Z]+d/', $str, $match) )
    print_r($match[0]);

方法4(一种更手动的变体)为了限制回溯步骤,您可以贪婪地从字符串的开头开始前进,按原子组逐个原子组,并以相同的方式按原子组而不是按字符回溯。

if ( preg_match('/^(?>[^x]*Kx)+[A-Z]+d/', $str, $match) )
    print_r($match[0]);

这篇关于PHP的preg_Match()返回最后一场比赛的位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆