好的,我已经尝试了一段时间,但是我似乎无法正确地做到这一点。我需要从字符串的 END 中删除 last 个不连续的重复单词/短语。例如,我要
Love in My Antonia Love in
和
Love in My Antonia Love
成为
Love in My Antonia
我尝试了无数模式,但没有成功。我最接近成功的是:
preg_replace('/\b(\w{2,})\b(?=.*?\\1)\W*/', ''
这会删除第一个出现(而不是最后一个),呈现为:
in My Antonia Love (ORIGINAL: "Love in My Antonia Love")
和
My Antonia Love in (ORIGINAL: "Love in My Antonia Love in")
请帮助! :)
更新(太平洋标准时间11月9日,2:00 PM):我应该澄清-如果可能的话-我希望解决方案保持在示例中显示的简单的1行紧凑格式中: / p>
preg_replace('/\b(\w{2,})\b(?=.*?\\1)\W*/', ''
我的示例已经非常完美地工作了,只是它删除了 first 匹配项而不是 last 匹配项。我希望有人可以适度地操纵我现有的代码,以便它删除最后一个匹配项(在字符串的末尾)而不是第一个匹配项。那比我想的还要复杂吗?
以前,我想出了一个版本,该版本可以在字符串中的任意位置找到两个连续的重复单词/短语,并将它们替换为一个:
preg_replace('~\b([\S \w]{3,})\K\b(?:\s*\1)+~', '',
这使“比萨饼披萨”成为“比萨饼”,“我去商店的我走到商店”变成“我去商店的”。太好了,我已经合并了该解决方案。现在,第二,我还需要“披萨是最好的披萨”才能成为“披萨是最好的”。同样,“牧羊犬是很棒的宠物狗”应该变成“牧羊犬是很棒的宠物”。因此,基本上,第一次出现在字符串中的位置无关紧要;重要的是在
答案 0 :(得分:1)
您可以在不使用正则表达式的情况下进行处理,方法是将句子拆分为组成词,然后手动检查最后两个词:
$input = "Love in My Antonia Love in";
$words = preg_split("/\s+/", $input);
$last = $words[count($words)-1];
$pattern = "/^(?=.*\b" . $last . "\b.*\b" . $last . "\b).*/";
if ($words[count($words) - 1] != $words[count($words) - 2] &&
preg_match($pattern, $input, $match)) {
array_pop($words);
}
$output = implode(" ", $words);
echo $input . "\n" . $output;
Love in My Antonia Love in
Love in My Antonia Love
答案 1 :(得分:1)
您在这里:
$s = preg_replace('/^\b([\w ]+)(.*?)\b(\1)$/i', '\\1\\2', $s);
测试:
$s = "Love in My Antonia Love in";
$s1 = "Love in My Antonia Love";
$s2 = "Love in My Antonia Love Not On End";
echo "Original:\n$s\n";
echo preg_replace('/^\b([\w ]+)(.*?)\b(\1)$/i', '\\1\\2', $s);
echo "\n";
echo "Original:\n$s1\n";
echo preg_replace('/^\b([\w ]+)(.*?)\b(\1)$/i', '\\1\\2', $s1);
echo "\n";
echo "Original:\n$s2\n";
echo preg_replace('/^\b([\w ]+)(.*?)\b(\1)$/i', '\\1\\2', $s2);
输出:
ZC-MGMT-04:~ jv$ php -q c.php
Original:
Love in My Antonia Love in
Love in My Antonia
Original:
Love in My Antonia Love
Love in My Antonia
Original:
Love in My Antonia Love Not On End
Love in My Antonia Love Not On End
====
更新:
Jason建议对单词末尾的'稍作更新:
preg_replace('/^\b([\w ]+)(.*?)\b\b(\1)(\'s)*\b$/i', '\\1\\2')
答案 2 :(得分:0)
您需要首先找到最长的重复子字符串,然后将其从主题字符串的末尾删除。可以使用preg_match_all
进行不区分大小写的搜索,然后使用preg_replace
省略搜索:
$str = 'Love in My Antonia Love in';
preg_match_all('~(\b\w++(?> \w++)*)(?=.*?\b\1)~i', $str, $matches);
$array = array_unique(array_map('strtolower', $matches[1]));
foreach ($array as $value) {
$str = preg_replace("~^.*\K(?<!\s)\s*\b$value~i", '', $str);
}
echo trim($str); // Love in My Antonia