例如我有以下字符串:
a_b__c___d____e
如何preg_replace 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
谢谢!
P.S。有趣的解决方案,不使用循环。如何用循环实现它(我认为)知道任何人。只需一个正则表达式和preg_replace。
答案 0 :(得分:2)
这是使用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 :(得分:1)
$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);
答案 2 :(得分:1)
这是内联解决方案:
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);
答案 3 :(得分:0)
提及php.net documenation使用修饰符e
是不鼓励的,
自PHP 5.5.0起,此功能已被弃用。非常不鼓励依赖此功能。
所以我们最好不要使用这个修饰符来实现我们的目标。
这是基于最新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]... */
即使在我们的PHP环境中仍然可以使用e
,通常最好使用回调函数 - 感谢回调我们避免了addslashes()
函数和字符串求值的相当不安全的组合,因为运行preg_replace与提到修饰符一次参与两个动作。
自版本4.0.5起,preg_replace_callback
已经可用,但function($matches) {}
是一个匿名函数,实际上是更新的语言功能,运行此代码,你需要在5.3版中使用PHP。 0或更新。
答案 4 :(得分:0)
您可以使用 \G
锚点逐个替换破折号,以确保从第一个 -
(后跟 n-1 个其他 -
)的位置到最后一个的位置连续一。这样你只需要检查第一个后面的破折号的数量:
echo preg_replace('~\G(?!^)_|_(?=_)~', '-', $str);
对于 n=2:
\G(?!^)_|_(?=_)
对于 n=3:
\G(?!^)_|_(?=_{2})
对于 n=4:
\G(?!^)_|_(?=_{3})
等
第一个分支 \G(?!^)_
只有在前一个位置匹配成功时才会成功。换句话说,这意味着这个分支将失败,直到下一个第二个分支成功。
第二个分支 _(?=_{n-1})
专用于第一个下划线。它使用前瞻断言检查以下下划线的数量。