从Preg_Replace_Callback中获取偏移量?



我正在尝试将使用javascript替换函数的javascript翻译成PHP。js 替换有一个使用偏移量和源字符串值的回调。我尝试使用 js 替换函数回调捕获偏移值preg_replace_callback但 PHP 不提供这个。

Javascript函数如下:

log.replace(/(?:<del>(.|n)*?</del>)|(?:<ins>(.|n)*?</ins>)/g, 
function(match, p1, p2, offsetval, strval) {
//does something with the offsetval and strval
});

有没有简单的方法可以使用preg_replace_callback或回调preg_match来做到这一点?它实际上只是匹配而不是替换。

问题是preg_match_all支持偏移捕获但不支持回调,preg_replace_callback支持回调但不支持偏移!!

我在 github 上找到了这个功能 https://gist.github.com/hakre/5376227

有什么更简单的方法吗?

不幸的是,我们没有任何参数可以跟踪preg_replace_callback偏移量,但有机会拥有它。我将您自己的正则表达式修改为性能更好的正则表达式,然后将此正则表达式添加到交替的另一侧:(?P<DOT>[sS]).如果交替的早期不匹配,则此正则表达式一次匹配一个字符。更准确地说,如果所需的正则表达式不匹配以保留偏移量,则需要向前迈出一步。

$str = "The color is <del>blue</del> or <ins>red!</ins>";
$offset = 0;
preg_replace_callback('/<(del|ins)>[sS]*?</1>|(?P<DOT>[sS])/',
function($m) use (&$offset) {
//...
$offset += strlen($m[0]); // $m[0] contains at least of character
},
$str
);

如果我在$offset行之前回显(echo $offset, "|", $m[0], "n";(,我们将得到以下输出:

0|T
1|h
2|e
3| 
4|c
5|o
6|l
7|o
8|r
9| 
10|i
11|s
12| 
13|<del>blue</del>
28| 
29|o
30|r
31| 
32|<ins>red!</ins>

对于那些正在寻找如何解决这个问题的人。我最后使用 strpos:

$string = 'some text';
$position = 0;
$callback = function (array $match) use ($string, &$position) {
$offset = strpos($string, $match[0], $position);
$position = $offset + strlen($match[0]);
// do your stuff
return 'replacement';
};
preg_replace_callback('/regex/', $callback, $string);

它将为您提供与其他preg_*函数相同的偏移量。以字节为单位。在使用多字节字符集时请记住这一点。

您可以使用具有offset()byteOffset()方法的轻量级T-Regx库

pattern('(?:<del>(.|n)*?</del>)')->replace($s)->first()->callback(function (Match $m) {
$match->offset();       // offset in characters
$match->byteOffset();   // offset in bytest
});

您可以在此处阅读有关它们的更多信息:https://t-regx.com/docs/match-offsets

最新更新