PHP регулярное выражение для поиска заменить строковые функции в строковые функции мб

Решение состояло в том, чтобы смотреть в будущее и смотреть в прошлое - концепция LookArounds в RegEx помогла мне решить мою проблему, так как замены были съедены друг от друга, когда я сделал замену

Поэтому мы некоторое время работали над тем, чтобы сделать некоторые переходы для некоторых из наших старых проектов и (возможно, плохих / старых привычек кодирования) и работаем над тем, чтобы сделать их готовыми к 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;

Файл $ имеет это содержимое:

<?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"));

не работает. 1-й и 3-й подстроки заменены правильными, но 2-й выглядит так:

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 ответ

Решение

Проблема в том, что некоторые символы, которые вы используете для разграничения проверок вызовов функций, используются при сопоставлении. Если вы переключите последнюю группу на позитивную, это решит проблему:

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

Ваше текущее выражение также не будет соответствовать вызовам функций в начале строки. Следующее обрабатывает это, а также немного упрощает:

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

Я создал пример на regex101.com.

Вы могли бы даже быть в состоянии сойти с рук:

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

куда \W будет соответствовать несловесному символу.

Обновить

Чтобы предотвратить сопоставление вызовов методов, вы можете добавить отрицательный вид сзади вашего шаблона:

$search_string = '/(^|[\s\[{;(:!=><?.,])(?<!->)' . $function_name . '(?=\s?\()/i';
                                        ^^^^^^^
Другие вопросы по тегам