替换多个字符串而不重叠
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>0
。 Table 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 在 替换密钥之前。如果这对用例来说是禁止的,应该可以修改它。
我已将示例更新为与搜索键之前的字符无关。
我有一个 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>0
。 Table 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 在 替换密钥之前。如果这对用例来说是禁止的,应该可以修改它。
我已将示例更新为与搜索键之前的字符无关。