24

我正在寻找一个可以找到重复字母的正则表达式。所以任何字母两次或更多,例如:

booooooot or abbott

我不会提前知道我要找的那封信。

这是我在面试中被问到,然后在面试中被问到的问题。没有多少人能正确理解。

4

11 回答 11

54

您可以找到任何字母,然后使用\1第二次(或更多)找到相同的字母。如果您只需要知道该字母,那么$1将包含它。否则,您可以将第二个匹配项连接到第一个匹配项上。

my $str = "Foooooobar";

$str =~ /(\w)(\1+)/;

print $1;
# prints 'o'
print $1 . $2;
# prints 'oooooo'
于 2008-10-07T15:00:06.043 回答
14

我认为您实际上想要这个而不是 "\w",因为它包括数字和下划线。

([a-zA-Z])\1+

好的,好的,我可以提示一下 Leon。将此用于 unicode-world 或 posix 的东西。

([[:alpha:]])\1+
于 2008-10-07T15:03:02.137 回答
9

我认为使用反向引用会起作用:

(\w)\1+

\w基本上是[a-zA-Z_0-9]这样,如果您只想匹配 A 和 Z 之间的字母(不区分大小写),请[a-zA-Z]改用。

(编辑:或者,就像 Tanktalus 在他的评论中提到的(以及其他人也回答过的那样) [[:alpha:]],这是对语言环境敏感的)

于 2008-10-07T14:58:58.650 回答
6

使用 \N 引用以前的组:

/(\w)\1+/g
于 2008-10-07T14:58:30.040 回答
4

您可能需要注意什么是字母,这取决于您的语言环境。使用 ISO Latin-1 将允许将带重​​音的西方语言字符匹配为字母。在以下程序中,默认语言环境无法识别 é,因此créé无法匹配。取消注释区域设置代码,然后它开始匹配。

另请注意,\w 包括数字和下划线字符以及所有字母。要仅获取字母,您需要获取非字母数字、数字和下划线字符的补码。这样就只剩下字母了。

通过将其作为问题来理解,这可能更容易理解:

“什么正则表达式匹配除 3 之外的任何数字?”
答案是:
/[^\D3]/

#! /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
于 2008-10-07T15:55:28.787 回答
3

以下代码将返回重复两次或更多次的所有字符:

my $str = "SSSannnkaaarsss";

print $str =~ /(\w)\1+/g;
于 2008-10-07T18:08:55.507 回答
2

只是为了踢,一种完全不同的方法:

if ( ($str ^ substr($str,1) ) =~ /\0+/ ) {
    print "found ", substr($str, $-[0], $+[0]-$-[0]+1), " at offset ", $-[0];
}
于 2008-10-08T04:01:45.700 回答
1

仅供参考,除了 RegExBuddy,gskinner.com 上的 RegExr 是一个真正方便的用于测试正则表达式的免费网站。处理([[:alpha:]])(\1+)得很好。

于 2008-10-07T19:28:48.247 回答
0

怎么样:

(\w)\1+

第一部分围绕一个字符创建一个未命名的组,然后反向引用查找相同的字符。

于 2008-10-07T14:58:52.537 回答
0

我认为这也应该有效:

((\w)(?=\2))+\2

于 2011-08-08T22:15:08.167 回答
0
/(.)\\1{2,}+/u

'u' 修饰符与 unicode 匹配

于 2012-05-23T21:42:17.523 回答