php regexp搜索将字符串函数替换为mb字符串函数

时间:2018-07-19 17:08:26

标签: regex multibyte multibyte-functions

解决方案是前瞻性和后瞻性-RegEx中LookArounds的概念帮助我解决了问题,因为当我进行替换时,替换项会被对方吃掉

因此,我们已经进行了一段时间的工作,以便对一些较旧的项目和(可能是不良/过时的编码习惯)进行一些过渡,并正在努力使它们成为php7就绪的。 在此过程中,我对项目的.php文件进行了一些调整,例如

当前的问题是,我在php字符串函数(strlen,substr等)中遇到丹麦字符的某些问题,并希望它们改用mb_string函数。根据我在互联网上可以使用“过载”功能阅读的内容,这种方法并不可行,因此我决定替换基于文件的搜索。

我的搜索替换功能现在看起来像这样(由于@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, "$1".$mb_function_name."$2$3", $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"));

不起作用。第一个和第三个子字符串被正确替换,但是第二个看起来像这样:

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

1 个答案:

答案 0 :(得分:0)

问题在于,用于分隔函数调用检查的某些字符已被匹配消耗。如果您将最后一组切换为positive lookahead,则可以解决此问题:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="section1">
  <div class="overflow" style="border: 1px solid green">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus at sem purus. Morbi ullamcorper nisi vitae nunc fermentum, quis hendrerit orci maximus. Cras malesuada auctor nibh, egestas aliquet enim tincidunt dictum. Maecenas enim lectus, fermentum
    eu massa a, malesuada egestas dui. Ut egestas velit eros, eu pulvinar metus bibendum ut. Aenean est justo, dictum eget ultricies eget, fermentum eu ex. Aliquam mollis sem in hendrerit malesuada. Praesent non enim molestie sapien laoreet pharetra sed
    eget diam. Vivamus placerat sem sed tortor lobortis, iaculis rhoncus purus condimentum. Nullam imperdiet nisi sit amet risus faucibus, vitae ultrices lectus aliquam.
  </div>
</div>

<div id="section2">
  <div class="overflow" style="border: 1px solid red">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus at sem purus. Morbi ullamcorper nisi vitae nunc fermentum, quis hendrerit orci maximus. Cras malesuada auctor nibh, egestas aliquet enim tincidunt dictum. Maecenas enim lectus, fermentum
    eu massa a, malesuada egestas dui. Ut egestas velit eros, eu pulvinar metus bibendum ut. Aenean est justo, dictum eget ultricies eget, fermentum eu ex. Aliquam mollis sem in hendrerit malesuada. Praesent non enim molestie sapien laoreet pharetra sed
    eget diam. Vivamus placerat sem sed tortor lobortis, iaculis rhoncus purus condimentum. Nullam imperdiet nisi sit amet risus faucibus, vitae ultrices lectus aliquam.
  </div>
</div>


<button id="swap">
  Swap it!
</button>

您当前的表达式也不会与该行开头的函数调用匹配。下面的方法可以解决这个问题,并简化一些事情:

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

我已经设置了an example on regex101.com

您甚至可以摆脱:

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

$search_string = '/(^|\W)' . $function_name . '(?=\s?\()/i'; 将与非单词字符匹配的地方。

更新

为防止匹配的方法调用,您可以在模式后面添加否定的外观:

\W