【问题标题】:Replace multiple strings without overlapping替换多个字符串而不重叠
【发布时间】:2017-03-31 11:43:50
【问题描述】:

我有一个 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 字符串,并且我替换了这两个字符串,这是错误的。所以我最终得到的结果类似于&lt;a href='SOME_LINK'&gt;Table 1&lt;/a&gt;0Table 10 根本不应该被替换(除非以后有另一对真正照顾 Table 10)。

有什么解决办法吗?我虽然想在字符串的搜索部分之后添加一个空格,但是文本中可能会有像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.

【问题讨论】:

  • 请做一件事,用您的输入和预期结果更新您的帖子
  • @WiktorStribiżew 非常好的主意。我正在考虑对项目进行排序,但 | 添加是我缺少的部分。
  • 如果那篇文章回答了你的问题,让我们把它当作一个骗子来关闭吧,好吗?
  • 很高兴,但请让我先试一试,看看我能不能让它工作。完成后我会立即报告:)

标签: php regex str-replace


【解决方案1】:

作为一种解决方法,如何通过键长度降序对替换数组进行排序并使用正则表达式仅替换未被&lt;a&gt; 标签封装的字符串?

这样您将在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.'/', '$1'.$value, $input);
}

// Show the result
print($input);

这个例子需要一个空格之前替换键。如果这对于用例来说是禁止的,则应该可以对其进行修改。
我已将示例更新为与搜索键之前的字符无关。

【讨论】:

  • 您能举例说明您的想法吗?
【解决方案2】:

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

您可以使用正则表达式搜索表格,例如,作为 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 处理一些正则表达式选项的方式与我个人预期的不同。这段代码在测试服务器中为我工作(用 2 或 10 替换“表 1”,只替换了正确的部分)。如果您想要不区分大小写的搜索,请在正则表达式中的 U 旁边添加 i。

【讨论】:

  • 这只是一个说明问题的例子。我无法控制输入文本,这取决于用户他们将使用什么样的字符串。我只是得到了清单和想要的结果,其余的就失控了。
  • 你的第二个解决方案似乎不起作用,它做了一大堆奇怪的替换,甚至没有接近靶心。
猜你喜欢
  • 1970-01-01
  • 2014-12-24
  • 1970-01-01
  • 1970-01-01
  • 2015-03-15
  • 2015-03-17
  • 1970-01-01
  • 1970-01-01
  • 2022-12-15
相关资源
最近更新 更多