如何在不重叠结果的情况下替换字符串中的多个字符串?

时间:2014-10-28 20:22:52

标签: php regex replace preg-replace str-replace

我试图从字符串中创建公共掩码,如下所示:

012abc.d+e_fg~hijk => 012{start}.d+{middle}_fg~{end}jk

取代:

$arrFromTo = array(
              'st' => '{pre}',
              'abc' => '{start}',
              'e' => '{middle}',
              'hi' => '{end}',
              'dd' => '{post}'
             );

相反,我会保持重叠的替换并取而代之(使用str_replace' s循环):

012{{pre}art}.d+{mi{post}le}_fg~{end}jk

因为st中找到了{start}dd中找到了{middle},而$str = 'abc.d+e_fg~hijk'; echo replace_vars($str); // Desired output: 012{start}.d+{middle}_fg~{end}kJ 中找到{{1}}。

您如何更换以下内容?

{{1}}

3 个答案:

答案 0 :(得分:6)

我可能会误解,但你似乎不需要正则表达式替换。它们是简单的,字面上的替代品。

$from = '012abc.d+e_fg~hijk';
$arrFromTo = array(
              'st' => '{pre}',
              'abc' => '{start}',
              'e' => '{middle}',
              'hi' => '{end}',
              'dd' => '{post}'
             );
$to = strtr($from, $arrFromTo); // 012{start}.d+{middle}_fg~{end}jk

strtr()太棒了。它需要一个非常易读的输入,它不会像循环中的问题那样重新替换。

答案 1 :(得分:2)

您可以像这样使用preg_replace

$str = '012abc.d+e_fg~hijk';
$arrFromTo = array(
              'st' => '{pre}',
              'abc' => '{start}',
              'e' => '{middle}',
              'hi' => '{end}',
              'dd' => '{post}'
             );

$reArr=array();
foreach($arrFromTo as $k=>$v){
   $reArr['/' . $k . '(?![^{}]*})/'] = $v;
}

echo preg_replace(array_keys($reArr), array_values($reArr), $str);
//=> 012{start}.d+{middle}_fg~{end}jk

这个正则表达式的核心是这个负面的外观:(?![^{}]*})

如果数组被{...}括起来,则会避免匹配数组的键,因为所有替换都包含在{...}中。

答案 2 :(得分:0)

这将按顺序搜索每个替换的字符串。如果找到一个,它将拆分字符串,并搜索字符串的其余部分以获取任何其他替换。

$str = '012abc.d+e_fg~hijk';

$rep = array(
    'st' => '{pre}',
    'abc' => '{start}',
    'e' => '{middle}',
    'hi' => '{end}',
    'dd' => '{post}'
);

$searched = '';

foreach ($rep as $key => $r) {
    if (strpos($str, $key) !== false) {

        $searched .= substr($str, 0, strpos($str, $key)) . $r;
        $str = substr($str, strpos($str, $key) + strlen($key));

    }
}

$searched .= $str;

echo $searched; //012{start}.d+{middle}_fg~{end}jk

它将按照您指定的顺序搜索并找到它们。