2017-03-04 93 views
3

我正在尝试编写一个函数来删除字符串中连续的重复单词。正则表达式找到的任何匹配都是至关重要的。换句话说...删除字符串中的连续重复单词

一个非常非常非常脏狗

应该成为...

一个非常肮脏的狗

我有一个正则表达式这似乎工作得很好(based on this post

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

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

我有这个目前...

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

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

回答

3

您可以使用正则表达式像\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个或多个序列: - 1
    • \s+或多个空格
    • \1\b - 反向引用存储在组值1个缓冲液(该值必须是一个全字)

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

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

+0

谢谢Wiktor!为了澄清,我以前的表达式还捕获单词不同的情况,所以这可能对某些人有用并值得投入记录。 – AdamJones

+0

我相信我的原始正则表达式可以处理不同的包含单词的单词。所以“非常非常”也会被捕获 – AdamJones

+0

啊好吧......我只是尝试了工作演示,并且似乎没有这样做 – AdamJones

0
<?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 
?> 

试试这个。它应该完整地返回一个副本。

+0

这是我的解决方案的轻量级版本,没有超过1个重复的单词支持。 –