Comment puis-je trouver des lettres répétées avec une regex Perl?

Je suis à la recherche d'une expression rationnelle qui trouvera des lettres répétitives. Donc, toute lettre deux fois ou plus, par exemple:

booooooot or abbott

Je ne connaîtrai pas la lettre que je cherche à l'avance.

C'est une question qui m'a été posée dans les interviews et ensuite posée dans les interviews. Pas si beaucoup de gens le font correctement.

23
demandé sur user000001 2008-10-07 18:56:20

11 réponses

, Vous pouvez trouver n'importe quelle lettre, puis utilisez \1 trouver la même lettre une seconde fois (ou plus). Si vous avez seulement besoin de connaître la lettre, alors $1 La contiendra. Sinon, vous pouvez concaténer la deuxième correspondance sur la première.

my $str = "Foooooobar";

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

print $1;
# prints 'o'
print $1 . $2;
# prints 'oooooo'
52
répondu Adam Bellaire 2008-10-07 15:00:06

Je pense que vous voulez réellement ceci plutôt que le "\ w " car cela inclut les nombres et le trait de soulignement.

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

Ok, ok, je peux prendre un indice Leon. Utilisez ceci pour le monde unicode ou pour les choses posix.

([[:alpha:]])\1+
14
répondu Keng 2008-10-07 15:57:26

Je pense que l'utilisation d'une référence arrière fonctionnerait:

(\w)\1+

\w est fondamentalement [a-zA-Z_0-9] donc si vous voulez seulement faire correspondre les lettres entre A et Z (sans tenir compte de la casse), utilisez [a-zA-Z] à la place.

(EDIT: ou, comme Tanktalus mentionné dans son commentaire (et comme d'autres l'ont répondu ainsi), [[:alpha:]], qui est sensibles aux paramètres régionaux)

9
répondu hasseg 2008-10-14 19:02:13

Utilisez \n pour faire référence aux groupes précédents:

/(\w)\1+/g
6
répondu Jonathan Lonowski 2008-10-07 14:58:30

Vous voudrez peut-être faire attention à ce qui est considéré comme une lettre, et cela dépend de vos paramètres régionaux. L'utilisation de L'ISO Latin-1 permettra de mettre en correspondance les caractères accentués de la langue occidentale sous forme de lettres. Dans le programme suivant, les paramètres régionaux par défaut ne reconnaissent pas é, et donc créé ne correspond pas. Décommentez le code de réglage des paramètres régionaux, puis il commence à correspondre.

Notez également que \w inclut des chiffres et le caractère de soulignement ainsi que toutes les lettres. Pour obtenir juste les lettres, vous devez prendre le complément des caractères non alphanum, des chiffres et des caractères de soulignement. Cela ne laisse que des lettres.

Cela pourrait être plus facile à comprendre en l'encadrant comme la question " Quelle expression régulière correspond à n'importe quel chiffre sauf 3?"et la réponse est /[^\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
4
répondu dland 2008-10-07 15:55:28

Le code suivant retournera tous les caractères, qui se répètent jamais deux fois ou plus.

Mon $ str = "SSSannnkaaarsss";

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

3
répondu 2008-10-07 18:08:55

Juste pour les coups de pied, une approche complètement différente:

if ( ($str ^ substr($str,1) ) =~ /\0+/ ) {
    print "found ", substr($str, $-[0], $+[0]-$-[0]+1), " at offset ", $-[0];
}
2
répondu ysth 2008-10-08 04:01:45

FYI, mis à part RegExBuddy, un vrai site gratuit pratique pour tester les expressions régulières est RegExr à gskinner.com . gère ([[:alpha:]])(\1+) bien.

1
répondu b w 2008-10-07 19:28:48

Que diriez-vous de:

(\w)\1+

La première partie crée un groupe sans nom autour d'un caractère, puis la référence arrière recherche ce même caractère.

0
répondu Joseph Pecoraro 2008-11-19 17:12:23

Je pense que cela devrait aussi fonctionner:

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

0
répondu karakays 2011-08-08 22:15:08
/(.)\\1{2,}+/u

Modificateur'u' correspondant à unicode

0
répondu Abdullah Aydın 2015-04-24 21:20:35