Как я могу найти повторяющиеся буквы с регулярным выражением Perl? - PullRequest
23 голосов
/ 07 октября 2008

Я ищу регулярное выражение, которое найдет повторяющиеся буквы. Так что любая буква дважды или больше, например:

booooooot or abbott

Я не буду знать письмо, которое ищу раньше времени.

Это вопрос, который мне задавали в интервью, а затем задавали в интервью. Не так много людей понимают это правильно.

Ответы [ 11 ]

53 голосов
/ 07 октября 2008

Вы можете найти любую букву, затем используйте \1, чтобы найти ту же букву во второй раз (или больше). Если вам нужно только знать письмо, тогда $1 будет содержать его. В противном случае вы можете объединить второе совпадение с первым.

my $str = "Foooooobar";

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

print $1;
# prints 'o'
print $1 . $2;
# prints 'oooooo'
14 голосов
/ 07 октября 2008

Я думаю, что вы на самом деле хотите это, а не "\ w", поскольку оно включает цифры и подчеркивание.

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

Хорошо, хорошо, я могу понять подсказку, Леон. Используйте это для мира юникода или для posix.

([[:alpha:]])\1+
9 голосов
/ 07 октября 2008

Я думаю, что использование обратной ссылки сработает:

(\w)\1+

\w - это в основном [a-zA-Z_0-9], поэтому, если вы хотите сопоставлять буквы только между A и Z (без учета регистра), используйте [a-zA-Z] вместо.

(РЕДАКТИРОВАТЬ: или, как упоминал Танкталус в своем комментарии (и, как другие также ответили), [[:alpha:]], который чувствителен к локали)

6 голосов
/ 07 октября 2008

Используйте \ N для ссылки на предыдущие группы:

/(\w)\1+/g
4 голосов
/ 07 октября 2008

Возможно, вы захотите позаботиться о том, что считать буквой, и это зависит от вашей локали. Использование 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
3 голосов
/ 07 октября 2008

Следующий код вернет все символы, которые повторяются дважды или более.

my $ str = "SSSannnkaaarsss";

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

2 голосов
/ 08 октября 2008

Просто ради ударов, совершенно другой подход:

if ( ($str ^ substr($str,1) ) =~ /\0+/ ) {
    print "found ", substr($str, $-[0], $+[0]-$-[0]+1), " at offset ", $-[0];
}
1 голос
/ 07 октября 2008

FYI, кроме RegExBuddy, реальный удобный сайт для тестирования регулярных выражений - RegExr на gskinner.com Ручки ([[:alpha:]])(\1+) красиво.

0 голосов
/ 24 мая 2012
/(.)\\1{2,}+/u

Соответствие модификатора 'u' юникоду

0 голосов
/ 09 августа 2011

Я думаю, это также должно работать:

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

...