【问题标题】:Removing consecutive duplicate words in a string删除字符串中的连续重复单词
【发布时间】:2017-03-04 22:50:22
【问题描述】:

我正在尝试编写一个删除字符串中连续重复单词的函数。保留正则表达式找到的任何匹配项至关重要。也就是说……

一条非常非常非常脏的狗

应该变成……

一条很脏的狗

我有一个似乎运行良好的正则表达式 (based on this post)

(\b\S+\b)(($|\s+)\1)+

但是我不确定如何使用 preg_replace (或者是否有更好的功能)来实现这一点。现在我让它删除所有匹配的重复单词,而不会留下一个完整的单词副本。我可以解析变量或特殊指令以保持匹配吗?

我现在有这个...

$string=preg_replace('/(\b\S+\b)(($|\s+)\1)+/', '', $string);

【问题讨论】:

  • 请注意,在交替中使用$ 是没有意义的,因为$\1 永远不会匹配(您甚至不使用多行修饰符。

标签: php regex preg-replace


【解决方案1】:

您可以使用\b(\S+)(?:\s+\1\b)+ 之类的正则表达式并替换为$1

$string=preg_replace('/\b(\S+)(?:\s+\1\b)+/i', '$1', $string);

regex demo

详情

  • \b(\S+) - 第 1 组捕获一个或多个以单词边界开头的非空白符号(也许 \b(\w+) 更适合这里)
  • (?:\s+\1\b)+ - 1 个或多个序列:
    • \s+ - 1 个或多个空格
    • \1\b - 对存储在第 1 组缓冲区中的值的反向引用(该值必须是整个单词)

替换模式是$1,替换反向引用引用存储在第 1 组缓冲区中的值。

注意/i不区分大小写修饰符将使\1不区分大小写,I have a dog Dog DOG将导致I have a dog

【讨论】:

  • 感谢维克托!澄清一下,我之前的表达也是捕捉不同大小写的单词。所以这可能对某些人有用,值得记录在案。
  • 我相信我的原始正则表达式适用于不同的大小写单词。所以“非常非常非常”也会被抓到
  • 啊好吧...我刚刚尝试了工作演示,但它似乎没有这样做
  • 非常感谢您对这个 Wiktor 的帮助!
  • @Tebe 使用preg_replace('/\b(\S+)(?:\s+\1\b)+/u', '$1', "молоко молоко хлеб колбаса");。此外,'/\b(\p{L}+)(?:\s+\1\b)+/u' 也可以使用。
【解决方案2】:
<?php
$text ='one one, two three, two';
$result_text = preg_replace("/\b(\w+)\s+\\1\b/i", "$1", $text);
echo "Result Text: ".$result_text; //one, two three, two
?>

试试这个。它应该原封不动地返回一份。

【讨论】:

  • 这是我的解决方案的轻量级版本,没有超过 1 个重复单词支持。
猜你喜欢
  • 2019-11-29
  • 2015-01-26
  • 1970-01-01
  • 2021-03-03
  • 2019-09-02
  • 1970-01-01
  • 1970-01-01
  • 2019-12-16
  • 1970-01-01
相关资源
最近更新 更多