3

我正在尝试用 PHP 翻译一个 javascript 脚本。到目前为止进展顺利,但我偶然发现了一些我一无所知的代码:

while (match = someRegex.exec(text)) {
    m = match[0];

    if (m === "-") {

       var lastIndex = someRegex.lastIndex,
           nextToken = someRegex.exec(parts.content);

       if (nextToken) {
              ...
       }

       someRegex.lastIndex = lastIndex;
    }
}

someRegex变量如下所示:

/[^\\-]+|-|\\(?:[0-3][0-7]{0,2}|[4-7][0-7]?|x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}|c[A-Za-z]|[\S\s]?)/g

exec 应该等同于 PHP 中的 preg_match_all:

preg_match_all($someRegex, $text, $match);
$match = $match[0];  // I get the same results so it works

foreach($match as $m){

   if($m === '-'){

     // here I don't know how to handle lastIndex and the 2nd exec :(

   }

}
4

2 回答 2

3

我根本不会使用那个lastIndex魔法——本质上你在每个索引上执行了两次正则表达式。如果您真的想这样做,则需要设置PREG_OFFSET_CAPTURE标志preg_match_all以便获得位置,添加捕获长度并将其用作下一个preg_match偏移量。

最好使用这样的东西:

preg_match_all($someRegex, $text, $match);
$match = $match[0]; // get all matches (no groups)

$len = count($match);
foreach($match as $i=>$m){

    if ($m === '-') {
        if ($i+1 < $len) {
            $nextToken = $match[$i+1];
            …
        }
        …
    }
    …
}
于 2013-03-26T15:43:56.633 回答
1

实际上,exec 不等同于 preg_match_all,因为 exec 在第一次匹配时停止(g 修饰符仅设置 lastIndex 值以循环遍历字符串)。它相当于preg_match。因此,您找到第一个匹配项,通过 $array 参数获取值,该值的偏移量(包含在 $flags 中)并通过设置偏移量(最后一个参数)继续搜索。

我想第二次执行不会有问题,因为你会做与 javascript 版本完全相同的事情。

请注意,我没有尝试过循环,但是一旦您弄清楚 preg_match 如何与可选参数完全配合(我将运行一些测试),它应该非常简单。

$lastIndex = 0;
while(preg_match($someRegex, $text, $match, PREG_OFFSET_CAPTURE, $lastIndex) {
  $m = $match[0][0];
  $lastIndex = $match[0][1] + strlen($m); //thanks Bergi for the correction

  if($m === '-') {
            // assuming the $otherText relate to the parts.content thing
    if(preg_match($someRegex, $otherText, $secondMatch, 0, $lastIndex)) {
      $nextToken = $secondMatch[0];
      ...
    }
  }
}

我想应该是这样(请原谅任何小错误,有一段时间没有做 php)。

于 2013-03-26T15:16:19.193 回答