[英]Replacing part of string with prefix and suffix
$str = ' I love [123] and [124] at (456). I hate [234] and [235] at (123).'
我想成功
$str = 'I love <a title="a">[123]</a> and <a title="b">[124]</a> at <a title="XX">(456)</a>. I hate <a title="c">[234]</a> and <a title="d">[235]</a> at <a title="ZZ">(123)</a>.'
要替换的文本是用大括号 () 或 [] 括起来的,可以从表 1 或表 2 中找到。
Table 1
123 | a
124 | b
234 | c
235 | d
Table 2
456 | XX
123 | ZZ
目前的方法
$text=explode(' ', $text);
for ($i=0; $i<count($text); $i++) {
for ($j=0; $j<count($table1Col1); $j++) {
if ($text[$i] == $table1Col1[$j])
$text[$i] = '<a href="#" title="'.$table1Col2[$j].'">'.$table1Col1[$j].'</a>';
}
for ($j=0; $j<count($table2Col1); $j++) {
if ($text[$i] == $table2Col1[$j])
$text[$i] = '<a href="#" title="'.$table2Col2[$j].'">'.$table2Col1[$j].'</a>';
}
}
如何改进代码以跳过不需要的循环?
我可能会考虑一种循环方式,但由于 arrays 具有相同的键,因此无法合并:
foreach($table1Col1 as $find => $repl) {
$text = str_replace("[$find]",
"<a title=\"$repl\">[$find]</a>",
$text);
}
foreach($table1Col2 as $find => $repl) {
$text = str_replace("($find)",
"<a title=\"$repl\">($find)</a>",
$text);
}
也许,这里的preg_replace_callback
会更好?
$str = 'I love [123] and [124] at (456). I hate [234] and [235] at (123).';
$t1 = ['123'=>'a', '124'=>'b', '234'=>'c', '235'=>'d'];
$t2 = ['456'=>'XX', '123'=>'ZZ'];
$f1 = implode('|', array_map(fn ($k) => preg_quote($k), array_keys($t1)));
$f2 = implode('|', array_map(fn ($k) => preg_quote($k), array_keys($t2)));
$res = preg_replace_callback("/\[($f1)\]|\(($f2)\)/", function($m) use($t1, $t2) {
// if first group has matched, then found key will be in `$m[1]`
// if second group has matched, then found key will be in `$m[2]`
$m1 = $m[1] ?? null;
$m2 = $m[2] ?? null;
if ($m1) {
// use first table
return '<a title="'.$t1[$m1].'">['.$m1.']</a>';
}
// use second table
return '<a title="'.$t2[$m2].'">('.$m2.')</a>';
}, $str);
结果:
I love <a title="a">[123]</a> and <a title="b">[124]</a> at <a title="XX">(456)</a>. I hate <a title="c">[234]</a> and <a title="d">[235]</a> at <a title="ZZ">(123)</a>.
假设字符串中的所有值都存在于表中,您可以使用替换|
捕获 2 组中的每个数字,并使用preg_replace_callback使用组值索引到 arrays 。
\[(\d+)]|\((\d+)\)
$str = ' I love [123] and [124] at (456). I hate [234] and [235] at (123).';
$table1Col1=["123" => "a", "124" => "b", "234" => "c", "235" => "d"];
$table1Col2 = ["456" => "XX", "123" => "ZZ"];
$pattern = "/\[(\d+)]|\((\d+)\)/";
$result = preg_replace_callback($pattern, function($match) use ($table1Col1, $table1Col2) {
return sprintf('<a title="%s">%s</a>',
array_key_exists(2, $match) ? $table1Col2[$match[2]] : $table1Col1[$match[1]]
, $match[0]
);
}, $str);
echo $result;
Output
I love <a title="a">[123]</a> and <a title="b">[124]</a> at <a title="XX">(456)</a>. I hate <a title="c">[234]</a> and <a title="d">[235]</a> at <a title="ZZ">(123)</a>.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.