How to replace multiple rows in a row without overlapping results?

I am trying to create common masks from a string as follows:

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

replace:

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

Instead, I keep overlapping replacements and get something like this (using the str_replace ):

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

Since st is in the already replaced {start} and dd , it is in {middle} .

How do you replace the following?

 $str = 'abc.d+e_fg~hijk'; echo replace_vars($str); // Desired output: 012{start}.d+{middle}_fg~{end}kJ 
+6
source share
3 answers

I might misunderstand, but you don't seem to need a regular expression to replace. They are simple, literal replacements.

 $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() is awesome. It requires very readable input and does not replace it in your loop.

+6
source

You can use preg_replace as follows:

 $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 

The core of this regular expression is this negative look: (?![^{}]*})

Which avoid matching array keys if they are enclosed in {...} , since all replacements are enclosed in {...} .

+2
source

This will result in a string search for each replacement in order. If he finds one, he will split the string and look for the rest of the string for any other replacements.

 $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 

He will search and find them in the order you specify.

0
source

Source: https://habr.com/ru/post/977378/


All Articles