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';
^^^^^^^