php 用于搜索将字符串函数替换为 mb 字符串函数的正则表达式

php regexp to search replace string functions to mb string functions

解决方案是查看前视和后视 - RegEx 中 LookArounds 的概念帮助我解决了我的问题,因为当我进行替换时替换被彼此吃掉了

因此,我们一直在努力对我们的一些旧项目和(可能是 bad/old 编码习惯)进行一些转换,并正在努力使它们 php7 准备就绪。 在此过程中,我对项目的 .php 文件进行了一些调整,例如

手头的问题是我在 php 字符串函数(strlen、substr 等)中遇到了丹麦字符的一些问题,希望他们改用 mb_string 函数。从我在互联网上看到的使用 "overload" 函数的内容来看,这不是可行的方法,因此我决定替换基于文件的搜索。

我的搜索替换功能现在看起来像这样(更新感谢@SeanBright

        $testfile = file_get_contents($file);
    $array = array (    'strlen'=>'mb_strlen',
                        'strpos'=>'mb_strpos',
                        'substr'=>'mb_substr',
                        'strtolower'=>'mb_strtolower',
                        'strtoupper'=>'mb_strtoupper',
                        'substr_count'=>'mb_substr_count',
                        'split'=>'mb_split',
                        'mail'=>'mb_send_mail',
                        'ereg'=>'mb_ereg',
                        'eregi'=>'mb_eregi',
                        'strrchr' => 'mb_strrchr',
                        'strichr' => 'mb_strichr',
                        'strchr' => 'mb_strchr',
                        'strrpos' => 'mb_strrpos',
                        'strripos' => 'mb_strripos',
                        'stripos' => 'mb_stripos',
                        'stristr' => 'mb_stristr'
    );
foreach($array as $function_name => $mb_function_name){
    $search_string = '/(^|[\s\[{;(:!\=\><?.,\*\/\-\+])(?<!->)(?<!new )' . $function_name . '(?=\s?\()/i';
    $testfile = preg_replace($search_string, "".$mb_function_name."", $test,-1,$count);
}
print "<pre>";
print $test;

$file 包含以下内容:

<?php
print strtoupper('test');
print strtolower'test');
print substr('tester',0,1);

print astrtoupper('test');
print bstrtolower('test');
print csubstr(('tester',0,1);
print [substr('tester',0,1)];
print {substr('tester',0,1)};
    substr('test',0,1);
substr('test',0,1);
    (substr('test',0,1));
    !substr();
    if(substr()==substr()=>substr()<substr()){
        ?substr('test');
    }
    "test".substr('test');
    'asd'.substr('asd');
    'asd'.substr('asd');
    substr( substr('asdsadsadasd',0,-1),strlen("1"),strlen("100"));
    substr (substr ('Asdsadsadasd',0,-1), strlen("1"),  strlen("100"));
    substr(substr(substr('Asdsadsadasd',0,-1),0,-1), strlen("1"),   strlen("100"));
    mailafsendelse(substr('asdsadsadasd',0,-1), strlen("1"),    strlen("100"));
    mail(test);
    substr ( tester );
    substr ( tester );
    mail mail mail mail ( tester );
    $mail->mail ();
    $mail -> mail ();
    new Mail();
    new mail ();
        strlen ( tester )*strlen ( tester )+strlen ( tester )/strlen ( tester )-strlen ( tester )

;

这里的重点是实际的 php 代码不一定是有效的语法。我只是想让它在不同的场景下工作

我的 regEx 问题是我无法找出这一行的原因:

substr(substr(substr('Asdsadsadasd',0,-1),0,-1), strlen("1"),   strlen("100"));

不工作。第一个和第三个 substr 被正确替换,但第二个看起来像这样:

mb_substr(substr(mb_substr('Asdsadsadasd',0,-1),0,-1), mb_strlen("1"),  mb_strlen("100"));

请注意,我的搜索字符串适用于函数名称前面的各种字符,并且要求函数名称之后的字符是“(”

在一个完美的世界中,我还想排除作为 类 中方法的字符串函数,例如:将发送电子邮件的 $order->mail()。我不想将其转换为 $order->mb_send_mail()

根据我的理解,所有参数都是相同的,所以应该没有问题。

可以在此处找到完整的脚本 https://github.com/welrachid/phpStringToMBString

问题是您用来分隔函数调用检查的某些字符正在被匹配使用。如果将最后一组切换为 positive lookahead,这将解决问题:

$search_string = '/([ \[{\n\t\r;(:!=><?\.,])'.($function_name).'([\ |\t]{0,1})(?=[(]{1})/i';
                                                                               ^^ Add these

您当前的表达式也不匹配行首的函数调用。以下处理并简化了一些事情:

$search_string = '/(^|[\s\[{;(:!=><?.,])' . $function_name . '(?=\s?\()/i';

我设置了an example on regex101.com

您甚至可以逃脱:

$search_string = '/(^|\W)' . $function_name . '(?=\s?\()/i';

其中 \W 将匹配非单词字符。

更新

为防止匹配方法调用,您可以在模式中添加否定回顾:

$search_string = '/(^|[\s\[{;(:!=><?.,])(?<!->)' . $function_name . '(?=\s?\()/i';
                                        ^^^^^^^