PHP: PCRE: как заменить повторяющийся символ - PullRequest
6 голосов
/ 17 мая 2011

например, у меня есть следующая строка:

a_b__c___d____e

Как preg_relace char _ to char '-', но только если часть '__...' содержит больше чем N повторяющихся _.

Надеюсь, вы меня понимаете))

source: a_b__c___d____e
cond: change '_' where 2 or more
result: a_b--c---d----e

или

source: a_b__c___d____e_____f
cont: change '_' where 4 or more
result: a_b__c___d----e-----f

Спасибо!

ps Интересное решение без использования петель.Как реализовать это с помощью петель (я думаю) знает кто-нибудь.Только одно регулярное выражение и preg_replace.

Ответы [ 4 ]

2 голосов
/ 17 мая 2011

Вот еще один, использующий модификатор e:

 $str = 'a_b__c___d____e_____f';
 echo preg_replace('/_{4,}/e', 'str_repeat("-", strlen("$0"))', $str);

Замените 4 на нужное вам число. Или как функция:

function repl($str, $char, $times) {
    $char = preg_quote($char, '/');
    $times = preg_quote($times, '/');
    $pattern = '/' . $char . '{' . $times . ',}/e',
    return preg_replace($pattern, 'str_repeat("-", strlen("$0"))', $str);
}
1 голос
/ 17 мая 2011

это встроенное решение:

preg_replace('/(_{2,})/ie', 'str_repeat("-",strlen("$1"));', $source);

и функция многократного использования:

$source = 'a_b__c___d____e_____f';


    function replace_repeatable($source,$char,$replacement,$minrepeat = 2)
    {
          return preg_replace('/(' . preg_quote($char) . '{' . $minrepeat . ',})/ie', 'str_repeat("' . $replacement . '",strlen("$1"));', $source);
    }

    $b = replace_repeatable($source,'_','-',4);
1 голос
/ 17 мая 2011
$source = 'a_b__c___d____e_____f';
function yourfunc($param)
{
    $count  = strlen($param);
    $return = '';
    for ($i = 0; $i < $count; $i++)
    {
        $return .= '-';
    }
    return $return;
}
echo preg_replace('#(_{4,})#e', 'yourfunc("$1");', $source);

Решение без функции обратного вызова и цикла намного сложнее для чтения.

preg_replace('#(_{4,})#e', 'implode("", array_pad(array(), strlen("$1"), "-"));', $source);
0 голосов
/ 08 июня 2013

Что касается php.net документация с использованием модификатора e не рекомендуется,

Эта функция устарела с версии PHP 5.5.0. Полагаться на эту функцию крайне не рекомендуется.

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

1012 *
*

Вот решение, основанное на современных инструментах PHP:

$source = 'a_b__c___d____e';

echo preg_replace_callback( "%(_{2,})%i", function($matches) {return str_repeat( "-", strlen($matches[1]) ); }, $source );
/* in callback function matches[0] is whole matched pattern, groups go like this matches[1],matches[2]... */

Даже если e все еще доступен в нашей среде PHP, обычно лучше использовать функцию обратного вызова - благодаря обратному вызову мы избегаем довольно небезопасного сочетания функции addslashes() и вычисления строки, поскольку запуск preg_replace с указанным модификатором включает оба действия за один раз.


A preg_replace_callback доступен с версии 4.0.5, но function($matches) {} - это анонимная функция, которая на самом деле является гораздо более новой функцией языка, для запуска этого кода вам нужен PHP в версии 5.3.0 или новее .

...