Php preg_每次替换时使用多个模式替换阵列

Php preg_每次替换时使用多个模式替换阵列,php,arrays,preg-replace,Php,Arrays,Preg Replace,我不认为我能一下子做到这一点,但我不屑于问:——) 我当然可以定义一对一的$pattern和$replacement数组,我可以重复定义$pattern数组和$replacement字符串,但我可以同时定义这两个数组吗 假设我有三套,比如: $p1 = array('sis','boom','bah'); $r1 = 'cheers'; $p2 = array('boo','hiss'); $r2 = 'jeers'; $p3 = array('guinness','heineken','b

我不认为我能一下子做到这一点,但我不屑于问:——)

我当然可以定义一对一的
$pattern
$replacement
数组,我可以重复定义
$pattern
数组和
$replacement
字符串,但我可以同时定义这两个数组吗

假设我有三套,比如:

$p1 = array('sis','boom','bah');
$r1 = 'cheers';

$p2 = array('boo','hiss');
$r2 = 'jeers';

$p3 = array('guinness','heineken','budweiser');
$r3 = 'beers';
我想在一个大草堆中,用它们各自的替代品替换模式的所有实例。我是否可以定义一个
preg\u replace
调用来完成此任务

$subject = 'sis + boo + guinness';
echo preg_replace(['/sis|boom|bah/','/boo|hiss/','/guinness|heineken|budweiser/'],['cheers','jeers','beers'],$subject);
// the result would be cheers + jeers + beers
替换 要替换字符串的字符串或数组。如果此参数为 字符串,并且模式参数是数组,则所有模式都将 由该字符串替换。如果模式和替换参数 如果是阵列,则每个阵列都将被替换 对应方如果替换数组中的元素少于 在阵列中,任何额外的阵列都将替换为空阵列 一串

如果subject是数组,则在上执行搜索和替换 subject的每个条目,返回值也是一个数组


我认为您需要将单词边界与基于正则表达式的函数结合起来

考虑一下这个
strtr()
demo:

$string="Rah rah, sis boom bah, I read a book on budweiser";
$p1 = array('sis','boom','bah');
$r1 = 'cheers';
$p2 = array('boo','hiss');
$r2 = 'jeers' ;
$p3 = array('guinness','heineken','budweiser');
$r3 = 'beers';

$replacements=array_merge(
    array_combine($p1,array_fill(0,sizeof($p1),$r1)),
    array_combine($p2,array_fill(0,sizeof($p2),$r2)),
    array_combine($p3,array_fill(0,sizeof($p3),$r3))
);
echo strtr($string,$replacements);
输出:

Rah rah, cheers cheers cheers, I read a jeersk on beers
//                                      ^^^^^ Oops
array (
  0 => '/\\b(?:sis|boom|bah)\\b/',                 // unescaped: /\b(?:sis|boom|bah)\b/
  1 => '/\\b(?:boo|hiss)\\b/',                     // unescaped: /\b(?:boo|hiss)\b/
  2 => '/\\b(?:guinness|heineken|budweiser)\\b/',  // unescaped: /\b(?:guinness|heineken|budweiser)\b/
)
array (
  0 => 'cheers',
  1 => 'jeers',
  2 => 'beers',
)
Rah rah, cheers cheers cheers, I read a book on beers

您只需使用管道内爆
指针
元素,并将它们包装在非捕获组中,以便单词边界应用于所有子字符串,如下所示:

代码:()

输出:

Rah rah, cheers cheers cheers, I read a jeersk on beers
//                                      ^^^^^ Oops
array (
  0 => '/\\b(?:sis|boom|bah)\\b/',                 // unescaped: /\b(?:sis|boom|bah)\b/
  1 => '/\\b(?:boo|hiss)\\b/',                     // unescaped: /\b(?:boo|hiss)\b/
  2 => '/\\b(?:guinness|heineken|budweiser)\\b/',  // unescaped: /\b(?:guinness|heineken|budweiser)\b/
)
array (
  0 => 'cheers',
  1 => 'jeers',
  2 => 'beers',
)
Rah rah, cheers cheers cheers, I read a book on beers
*注:

单词边界
\b
确保整个单词匹配,避免意外的不匹配


如果需要区分大小写,只需在每个正则表达式模式的末尾使用
i
标志。e、 g.
/\b(?:sis | boom | bah)\b/i

如果使用正则表达式,则可以在模式中使用
(sis | boom | bah)
,否则str | u replace可以使用一个值数组进行搜索,并使用单个值进行替换。
str |u replace()
将不考虑单词边界,当在另一个子字符串中发现一个子字符串时,可能会返回意外结果。要完全暴露不包括单词边界的问题。。。如果你有
$string=”我姐姐花500泰铢买了一个回力棒'并使用
echo preg_替换('/sis | boom | bah/'、'cheers'、$string)
然后你会得到这样一堆乱七八糟的东西:
我的啦啦队队员花了500 cheerst买了一个啦啦队
,但却没有预定的替代品。当
boo
更改为
book
时,你的方法会产生意外的结果。请参阅我关于单词边界的回答。@mickmackusa,在上面的链接
$subject='sis+book+guinness'
导致了
cheers+jeersk+beers
,这是正常的预期行为,如果你只想替换整个单词
boo
,而不是
book
的开头,明白我的意思吗?啊哈!是的,将每个模式数组更改为单个regexp将再次将其减少到1:1。这有点痛苦,但introde()是一个很酷的技巧,使它再次编程。我会期待更多的想法,但这可能会得到复选标记时,我可以再次期待明天:-)谢谢!