2014-04-11 89 views
1

正则表达式,匹配连续两次或多次连续两次或更多次具有相同单词的任何输入行。假设有连续 单词之间有一个空格perl正则表达式匹配重复单词

if($line!~m/(\b(\w+)\b\s){2,}/{print"No match\n";} 
    { print "$`";  #print out first part of string 
     print "<$&>";  #highlight the matching part 
     print "$'";  #print out the rest 
    } 

这是最好的,我得到了这么远,但也有一些是错误的 纠正我,如果我错了,

\b开始用字边界

(\w+)后跟一个单词或多词

\b以单词边界结尾

\s一个空格

{2,}检查,如果这件事情重复2次以上

有什么错我的表情

回答

1

这应该是你要找的内容的一种方式:(?:\b(\w+)\b) (?:\1(?: |$))+

另外,不要使用\s时你只是在寻找空格,因为它可能会匹配换行符或其他空格字符。简单的空格不是正则表达式中的分隔符或特殊字符,所以只需输入空格即可。如果您希望它更直观,可以使用[ ]

+0

你介意给我解释一下这个表达吗?我不太明白第二部分 – user3422317

+0

第二部分以'\ 1'开头,它是对正则表达式中第一个捕获组(包含在(()中的东西)的引用。这意味着它告诉正则表达式“记住”它用'(\ w)'找到的内容,然后在'\ 1'处再次找到它。之后是一个非捕获组(使用'(?:)')查找正常空间或字符串的结尾。整个模式的后半部分被自己的捕获组所包围,这个捕获组可以用'+'作为整体进行量化(如果它不在一个组中,那么'+'只适用于'(?:| $)'。 – CAustin

0

你实际上并没有检查,看它是否是一个的重复着同样的话。要做到这一点,你需要使用捕捉反向引用:

if ($line =~ m/\b(\w+)(?:\s\1){2,}\b/) { 
    print "matched '$1'\n"; 
} 

此外,任何时候你正在测试一个正则表达式,它,如果你创建的实例一起工作列表是有帮助的。下面演示了这样做,使用__DATA__

use strict; 
use warnings; 

while (my $line = <DATA>) { 
    if ($line =~ m/\b(\w+)(?:\s\1){2,}/) { 
     print "matched '$1'\n"; 
    } else { 
     print "no match\n"; 
    } 
} 

__DATA__ 
foo foo 
foo bar foo 
foo foo foo 

输出

no match 
no match 
matched 'foo' 
+0

谢谢,我使用这个网站[链接](http://regex101.com/R/cU5lC2#PC RE)也有帮助 – user3422317

+0

这段代码有一个错误,当我尝试匹配'fo foo foo'时,它突出显示'fo fo foo foo。这个词应该以一个空格结束。我也不太了解'?:\ s \ 1'。我知道他们分开的意思。 – user3422317

+0

如果单词应该以空格结尾,只需在末尾添加一个额外的单词边界'\ b'。 – Miller

1

我在regexr.com上试过了卡斯汀的回答,结果并不是我所期望的。另外,不需要所有非捕获组。

我正则表达式:

(\b(\w+))(\2)+ 

字边界,接着(1个或多个字字符)[第2组],随后是一个或多个:空间,组2

这下一个一个与\s+替换空间,概括的词之间的分离是1个或多个任何类型的空白的:

(\b(\w+))(\s+\2)+