Php 如何在海量数据中进行预存替换

Php 如何在海量数据中进行预存替换,php,regex,preg-replace,upgrade,modx-revolution,Php,Regex,Preg Replace,Upgrade,Modx Revolution,我刚刚制作了一个升级脚本,用于将所有MODX代码段标记替换为更新的格式: 旧的:[~123~] 新的:[[~123]] (当然,123——这是一个例子——有很多不同的数字) 我还想将所有自定义的旧的代码片段替换为新的: 旧代码段格式: [!MySnippetName? &param1=`value1` &param2=`value2` !] 新的: [[!MySnippetName? &param1=`value1` &param2=`value2` ]] (

我刚刚制作了一个升级脚本,用于将所有MODX代码段标记替换为更新的格式:

旧的:
[~123~]

新的:
[[~123]]

(当然,123——这是一个例子——有很多不同的数字)

我还想将所有自定义的旧的代码片段替换为新的:

旧代码段格式:

[!MySnippetName? &param1=`value1` &param2=`value2` !]
新的:

[[!MySnippetName? &param1=`value1` &param2=`value2` ]]
(当然,
¶m1=value1¶m2=value2
只是一个示例,在实际代码片段中有所不同)

如何使用preg_replace函数进行全局替换? 我应该这样创造:

$doc[ 'content' ] = $this->preg_replace_all(
        array(
                '/\[~([0-9]+)~\]/',
                '\[!LatestUpdates(.*)!\]',
                '\[!ArticleSummary(.*)!\]',
            ), array(
                '[[~\1]]',
                '[[!LatestUpdates\1]]',
                '[[!ArticleSummary\1]]',
            ),
            $doc[ 'content' ]
        );
UPDATE modx_site_content SET content = REPLACE(content, '[!', '[[!');
preg\u replace\u all功能:

private function preg_replace_all( $find, $replacement, $s )
{
    while(preg_match($find, $s)) {
        $s = preg_replace($find, $replacement, $s);
    }
    return $s;
}

但它不起作用。请帮忙解决这个问题。提前感谢。

函数
preg\u replace
已经执行全局替换,并且由于只替换匹配的子字符串,因此不需要使用
preg\u match
测试这些子字符串是否存在

您可以将三种模式减少为一种模式:

$pattern = '/\[(?|(!LatestUpdates|!ArticleSummary)(.*?)!]|(~)([0-9]+)~])/';
$replacement = '[[$1$2]]';
$doc['content'] = preg_replace($pattern, $replacement, $doc['content']);
此模式使用允许捕获组在每个备选方案中具有相同编号的功能

如果可能(如果它不改变您想要保留的标记),您可以使用
strtr

$doc['content'] = strtr($doc['content'], array('[!'=>'[[!', '[~'=>'[[~', '~]'=>']]', '!]'=>']]'));

请注意,如果您可以使用它,请不要犹豫,因为这种方式要快得多。

为什么要使用PHP来完成此操作-您是否编写了一个插件,在解析页面时将所有Evolution标记转换为Revolution格式

如果是这样的话,这是低效的,最好替换存储内容、模板、块等的数据库中的所有标记

您可以使用如下查询轻松完成此操作:

$doc[ 'content' ] = $this->preg_replace_all(
        array(
                '/\[~([0-9]+)~\]/',
                '\[!LatestUpdates(.*)!\]',
                '\[!ArticleSummary(.*)!\]',
            ), array(
                '[[~\1]]',
                '[[!LatestUpdates\1]]',
                '[[!ArticleSummary\1]]',
            ),
            $doc[ 'content' ]
        );
UPDATE modx_site_content SET content = REPLACE(content, '[!', '[[!');
对所有其他打开和关闭标记以及其他数据库表重复此操作


在尝试此操作之前备份数据库…

默认情况下,preg_replace执行全局替换。你不需要写一个新函数,也不需要使用preg_match。我想使用strtr,但我担心意外的额外替换。但是感谢3行regexp解决方案。我不知道如何在preg_replace中替换捕获组,但我发现这比我想象的要容易得多。@SergiyMatrunchyk:分支重置功能确实是一个非常方便的功能。但是,如果您想执行更复杂的替换,请查看
preg\u replace\u回调
函数。关于“意外额外替换”,请记住,大多数情况下,模板系统的设计都是为了避免歧义。