繁体   English   中英

用前缀和后缀替换部分字符串

[英]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+)\)

正则表达式演示| Php 演示

$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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM