PHP:PCRE:如何替换可重复字符

发布于 2024-11-07 14:11:36 字数 486 浏览 5 评论 0原文

例如我有以下字符串:

a_b__c___d____e

How to 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

谢谢!

ps 有趣的解决方案,无需使用循环。如何用循环实现它(我认为)任何人都知道。只需一个正则表达式和 preg_replace。

for example I have following string:

a_b__c___d____e

How to preg_replace char _ to char '-', but only if part ' __...' contains more than N repeated _.

I hope you understand me ))

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

or

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

Thanks!

p.s. Interesting solution without using loops. How implement it with loops (I think) know anybody. Just a one regex and preg_replace.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

掩于岁月 2024-11-14 14:11:36

这是使用 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);
}

Here is another one using the e modifier:

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

Replace 4 by the number you need. Or as function:

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);
}
千と千尋 2024-11-14 14:11:36
$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);
$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);

A solution without callback function and loop is much harder to read.

preg_replace('#(_{4,})#e', 'implode("", array_pad(array(), strlen("$1"), "-"));', $source);
尘世孤行 2024-11-14 14:11:36

这是内联解决方案:

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

this is inline solution :

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

and reusable funciton:

$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);
这个俗人 2024-11-14 14:11:36

参考 php.net 文档 使用修饰符 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]... */

即使 e 在我们的 PHP 环境中仍然可用,通常使用回调函数更好 - 感谢回调,我们避免了相当不安全的 addslashes() 函数和字符串评估,因为使用提到的修饰符运行 preg_replace 会同时执行这两个操作。

preg_replace_callback 自版本 4.0.5 起可用,但 function($matches) {} 是一个匿名函数,实际上是更新的语言功能,要运行此代码,您需要 5.3.0 或更高版本的 PHP

As referring to php.net documenation using modifier e is discouraged,

This feature has been DEPRECATED as of PHP 5.5.0. Relying on this feature is highly discouraged.

so we'd better to achieve our goal without using this modifier.

Here's solution based on up to date PHP's tools:

$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]... */

Even with e still available in our PHP environment, it is generally better to use callback function - thank's to callback we avoid rather unsafe combination of addslashes() function and string evaluation, since running preg_replace with mentioned modifier engages both actions at a time.

A preg_replace_callback has been available since version 4.0.5, but function($matches) {} is an anonymous function which is actually much newer language feature, to run this code u need PHP in version 5.3.0 or newer.

听风念你 2024-11-14 14:11:36

您可以使用 \G 锚点逐个替换破折号,以确保与第一个 - 位置的连续性(后跟 n-1 个其他 -< /code>) 到最后一个。这样,您只需检查第一个破折号之后的破折号数量:

echo preg_replace('~\G(?!^)_|_(?=_)~', '-', $str);

demo

for n =2:

\G(?!^)_|_(?=_)

for n=3:

\G(?!^)_|_(?=_{2})

for n=4:

\G(?!^)_|_(?=_{3})

等等。

仅当前一个位置成功匹配时,第一个分支 \G(?!^)_ 才会成功。换句话说,这意味着该分支将失败,直到下一个分支成功。
第二个分支 _(?=_{n-1}) 用于第一个下划线。它使用前瞻断言检查以下下划线的数量。

You can replace the dashes one by one using the \G anchor to ensure a contiguity from the position of the first - (followed by n-1 other -) to the last one. This way you only have to check the number of following dashes after the first one:

echo preg_replace('~\G(?!^)_|_(?=_)~', '-', $str);

demo

for n=2:

\G(?!^)_|_(?=_)

for n=3:

\G(?!^)_|_(?=_{2})

for n=4:

\G(?!^)_|_(?=_{3})

etc.

The first branch \G(?!^)_ succeeds only when there's a successfull match at the previous position. In other words, that means this branch will fail until the next second branch succeeds.
The second branch _(?=_{n-1}) is devoted to the first underscore. It checks using a lookahead assertion the number of following underscores.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文