我已经看到很多关于此问题的答案,但由于这个问题有点具体,我仍然需要一些帮助。我尝试使用preg_replace()
修饰符更新包含\e
的Blogstudio&n; Fix Serialization脚本。
有问题的代码是:
$data = preg_replace('!s:(\d+):([\\\\]?"[\\\\]?"|[\\\\]?"((.*?)[^\\\\])[\\\\]?");!e', "'s:'.strlen(unescape_mysql('$3')).':\"'.unescape_quotes('$3').'\";'", $data);
我的困惑在于:
/e
修饰符引起的转义引号?$3
?我已经重写了它,但仍然遇到警告和其他问题,所以结果与预期不一样:
$data = preg_replace_callback(
'!s:(\d+):([\\\\]?"[\\\\]?"|[\\\\]?"((.*?)[^\\\\])[\\\\]?");!',
function($d) {
$length = strlen(unescape_mysql($d[3]));
$value = unescape_quotes($d[3]);
$result = 's:' . $length . ':\"' . $value . '\";';
return 's:' . $length . ':\"' . $value . '\";'
},
$data
);
答案 0 :(得分:2)
问题:
s:(\d+): # group 1
( # group 2
[\\\\]?"[\\\\]?"
|
[\\\\]?"
((.*?)[^\\\\]) # group 3 (and 4)
[\\\\]?"
)
;
正如您所看到的那样,组内有2个分支的交替2.组3(和4)位于第二个分支中,当第一个分支成功时,这些组未定义。
让我们清理模式,删除无用的捕获组:
s:\d+:
(?:
[\\\\]? " [\\\\]? "
|
[\\\\]? "
(.*? [^\\\\]) # group 1
[\\\\]? "
)
;
现在目标组是组1,但分支问题仍然存在。有两种可能的解决方法:
isset
。第一种方式:
$data = preg_replace_callback(
'~s:\K\d+:(?:[\\\\]?"[\\\\]?"|[\\\\]?"(.*?[^\\\\])[\\\\]?");~',
function ($m) {
return (isset($m[1]))
? strlen(unescape_mysql($m[1])) . ':\"' . $m[1] . '\";'
: '0:\"\";';
},
$data
);
第二种方式(使用分支重置功能):
$data = preg_replace_callback(
'~s:\K\d+:(?|[\\\\]?"[\\\\]?"()|[\\\\]?"(.*?[^\\\\])[\\\\]?");~',
function ($m) {
return strlen(unescape_mysql($m[1])) . ':\"' . $m[1] . '\";';
},
$data
);
在分支重置组中,捕获组在每个分支中具有相同的编号,为了解决您的问题,您只需要在第一个分支中创建一个空的捕获组:
(?| # open a branch reset group
foo
() # capture group 1
|
bar
(baz) # capture group 1 (too)
)