php preg_match返回上一场比赛的位置

and*_*rew 9 php regex preg-match

preg_match($pattern, $subject, $matches, PREG_OFFSET_CAPTURE); 
Run Code Online (Sandbox Code Playgroud)

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

或者我必须返回所有匹配的位置preg_match_all并使用最后一个元素$matches

Cas*_*yte 24

PHP没有从右到左搜索字符串的正则表达式方法(如在.net中).有几种可能的方法可以解决这个问题:

  • 使用preg_match_allwith PREG_SET_ORDERflag end($matches)并将为您提供最后一个匹配集
  • strrev使用preg_match 与字符串反转并构建"反转"模式
  • 使用preg_match和构建锚定在字符串末尾的模式,确保在字符串结束之前不再出现搜索到的掩码
  • 之前使用贪婪量词并用于\K在所需位置开始匹配结果.一旦到达字符串的末尾,正则表达式引擎将回溯直到找到匹配.

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

方式1:

if ( preg_match_all('/x[A-Z]+\d/', $str, $matches, PREG_SET_ORDER) )
    print_r(end($matches)[0]);
Run Code Online (Sandbox Code Playgroud)

方式2:

if ( preg_match('/\d[A-Z]+x/', strrev($str), $match) )
    print_r(strrev($match[0]));
Run Code Online (Sandbox Code Playgroud)

方式3:

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

方式3(变体):

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

方式4:

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

方式4(变体):要限制回溯步骤,可以将可能的块包含在原子组中:

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