0

我有一个字符串数组

$array = array("are", "finite", "get", "er");

和一个字符串

$string = "You are definitely getting better today";

我期待这个输出

You today

我想有效地从字符串中删除所有数组值,如果数组值是字符串中单词的一部分,则整个单词也必须从字符串中删除。

这是我目前正在处理的代码

foreach ($array as $a)
{
    $string = str_replace($a, "", $string);
}
echo $string;

它从字符串中删除数组值,但不会删除包含数组值的单词。

编辑:

由于我的字符串是用户提供的并且大约 4096 个字符长,请有人指导我哪个答案在速度和内存使用方面更有效。

4

2 回答 2

2

试试这个(正则表达式方法):

$patterns = ["are", "finite", "get", "er"];
$string = "You are definitely getting better today";

$re = '\w*('.implode('|', $patterns).')\w*';
$string = preg_replace('#'.$re.'#', '', $string);
$string = preg_replace('#\h{2,}#', ' ', $string);
echo $string;
于 2018-07-16T06:44:27.583 回答
1

这是一个版本strtok

$patterns = ["are", "finite", "get", "er"];
$string = "You are definitely getting better today";

$tok = strtok($string, ' ');
while ($tok !== false) {
    foreach ($patterns as $pattern) {
        if (strpos($tok, $pattern) !== FALSE) {
            $string = str_replace("$tok ", '', $string);
        }
    }
    $tok = strtok(' ');
}
echo $string;

这是另一个正则表达式版本:

$string = "You are definitely getting better today";
$patterns = ["are", "finite", "get", "er"];

$regex = sprintf(
    "#\w*(%s)\w*\h*#",
    implode('|', array_map('preg_quote', $patterns))
);
echo preg_replace($regex, '', $string);

该模式与此页面上的其他模式基本相同,但它不会使删除空格成为额外的步骤,而是以单一模式代替:

正则表达式模式 \w*(are|finite|get|er)\w*\h*

关于您的评论:

请修改您的第二个代码,以便如果单词https://www.get.co在字符串中,则必须删除整个单词https://www.get.co

单词 ( \w) 始终与 ASCII 字符匹配[A-Za-z0-9_]。因此,它不会匹配正斜杠、点或冒号。您需要按如下方式扩展字符类:

"#[\w/:.]*(%s)[\w/:.]*\h*#"

根据性能:根据您的一些输入对其进行基准测试。

于 2018-07-16T07:11:09.723 回答