我正在寻找一个正则表达式,可以找到重复出现的字母。例如,任何出现两次或更多的字母:
booooooot or abbott
我不会提前知道我要查找的信件。
这是我在面试中被问到的问题,也是我问其他人的问题。很少有人能回答正确。
你可以找到任何一个字母,然后使用\1
来再次查找该字母(或更多)。如果你只需要知道这个字母,那么$1
将包含它。否则,你可以将第二次匹配的内容连接到第一次上。
my $str = "Foooooobar";
$str =~ /(\w)(\1+)/;
print $1;
# prints 'o'
print $1 . $2;
# prints 'oooooo'
我认为你实际上想要这个而不是"\w",因为它包括数字和下划线。
([a-zA-Z])\1+
好的,好的,我明白了Leon的意思。将其用于Unicode世界或POSIX相关内容。
([[:alpha:]])\1+
我认为使用反向引用会起作用:
(\w)\1+
\w
基本上等同于[a-zA-Z_0-9]
,所以如果你只想匹配A到Z之间的字母(不区分大小写),请使用[a-zA-Z]
。
(编辑:或者,就像Tanktalus在他的评论中提到的那样(以及其他人已经回答的那样),[[:alpha:]]
,这是与语言环境有关的)
使用\N来引用之前的组:
/(\w)\1+/g
#! /usr/local/bin/perl
use strict;
use warnings;
# uncomment the following three lines:
# use locale;
# use POSIX;
# setlocale(LC_CTYPE, 'fr_FR.ISO8859-1');
while (<DATA>) {
chomp;
if (/([^\W_0-9])\1+/) {
print "$_: dup [$1]\n";
}
else {
print "$_: nope\n";
}
}
__DATA__
100
food
créé
a::b
my $str = "SSSannnkaaarsss";
print $str =~ /(\w)\1+/g;
只是为了好玩,完全不同的方法:
if ( ($str ^ substr($str,1) ) =~ /\0+/ ) {
print "found ", substr($str, $-[0], $+[0]-$-[0]+1), " at offset ", $-[0];
}
顺便说一下,除了 RegExBuddy 之外,另一个非常方便的免费正则表达式测试网站是 gskinner.com 上的 RegExr。 它可以很好地处理 ([[:alpha:]])(\1+)
。
这样怎么样:
(\w)\1+
第一部分围绕一个字符创建了一个未命名的组,然后反向引用查找相同的字符。
我认为这个也可以工作:
((\w)(?=\2))+\2