替换多个字符串而不重叠

Replace multiple strings without overlapping

我有一个 PHP 应用程序,我必须在其中用它们各自的链接替换一大堆字符串。基本上我得到了一个可能的替代品列表,看起来像这样:

"Table 1" => "<a href='SOME_LINK'>Table 1</a>"
"Table 2" => "<a href='SOME_LINK'>Table 2</a>"
...
"Table 10" => "<a href='SOME_LINK'>Table 10</a>"
"Table 11" => "<a href='SOME_LINK'>Table 11</a>"

我遍历每一对,然后调用 str_replace 每对值。问题是,即使在第一次传递时,我也捕获了 Table 10 字符串和 Table 1 字符串,并且我将两者都替换了,这是错误的。所以我最终得到的结果类似于 <a href='SOME_LINK'>Table 1</a>0Table 10 根本不应该被替换(除非后来有另一对实际处理 Table 10)。

有什么变通办法吗?我虽然想在字符串的搜索部分后添加一个空白 space,但是可能在文本中包含 Table 1, 之类的内容,然后根本不匹配。我也考虑过使用正则表达式来替换,但不确定是否有语法可以解决上述问题。

编辑: 为了提高阅读理解能力,这里是这个问题的预期输入和输出。 条件:

"Table 1" => "<a href='SOME_LINK'>Table 1</a>"
"Table 10" => "<a href='SOME_LINK'>Table 10</a>"

输入:

We have some text here.
It has words like Table 1, Table 2 and also Table 10.
Those need to be replaced.

输出:

We have some text here.
It has words like <a href='SOME_LINK'>Table 1</a>, Table 2 and also <a href='SOME_LINK'>Table 10</a>.
Those need to be replaced.

由于评论有更多信息,再次修改答案。

您可以使用正则表达式搜索 table,例如 PHP 代码:

$input = "We have some text here.
It haswords like Table 1, Table 2 and also Table 10.
Those need to be replaced.";

$output = preg_replace("/(Table 1)(?![\d])/U", "<a href=\"LINK HERE\">LINK TEXT</a>", $input);

echo "Input:<br>".$input."<br><br>Output:<br>".$output;

似乎 PHP 处理某些正则表达式选项的方式与我个人预期的不同。这段代码在测试服务器上对我有用(将 "Table 1" 替换为 2 或 10 只替换了正确的部分)。如果您想要不区分大小写的搜索,请在正则表达式中的 U 旁边添加 i。

作为解决方法,如何按键长度降序对数组进行替换并使用正则表达式仅替换未被 <a> 标签封装的字符串?

这样您就可以在 Table 1 之前替换 Table 10,并且不会进行任何双重替换。

编辑: 这是请求的示例

$input = "We have some text here.
  It has words like Table 1, Table 2 and also Table 10.
  Those need to be replaced.";

$replacements = [
  "Table 1" => "<a href='SOME_LINK'>Table 1</a>",
  "Table 2" => "<a href='SOME_LINK'>Table 2</a>",
  "Table 10" => "<a href='SOME_LINK'>Table 10</a>",
];

uksort($replacements, function($a, $b) {
  return strlen($b) - strlen($a);
});

foreach ( $replacements as $key => $value ) {
  $input = preg_replace('/([^>])'.$key.'/', ''.$value, $input);
}

// Show the result
print($input);

此示例需要 space 替换密钥之前。如果这对用例来说是禁止的,应该可以修改它。
我已将示例更新为与搜索键之前的字符无关。