2009-03-13 5 views
33

Un ami m'a posé cette question et j'ai été perplexe: Y at-il un moyen de créer une expression régulière qui correspond à une séquence du même personnage? Par exemple, match sur 'aaa', 'bbb', mais pas 'abc'?Quelle regex peut correspondre à des séquences du même caractère?

m|\w{2,3}| 

Ne ferait pas l'affaire car il correspondrait à 'abc'.

m|a{2,3}| 

ne ferait pas l'affaire car il ne correspondrait pas à 'bbb', 'ccc', etc.

Répondre

64

Bien sûr chose! Le regroupement et les références sont vos amis:

(.)\1+ 

Correspondra à 2 occurrences ou plus du même caractère. Pour mot caractères constitutifs uniquement, utilisez \w au lieu de ., i.e. .:

(\w)\1+ 
+0

Ceci ne correspondra qu'à certains caractères, et manquera de '###'. Les exemples qu'il a donnés sont des caractères alphabétiques, mais ils ne demandent pas seulement des caractères alphabétiques. Je remplacer '\ w' par '.'. – gpojd

+0

Eh bien, sur la base des exemples non-opérationnels que l'auteur de l'interrogation a donnés, j'ai supposé qu'il/elle voulait uniquement faire correspondre les caractères alphabétiques. J'aurais dû exprimer cela dans l'explication cependant. –

+0

Que signifie le slash 1? – CodyBugstein

0

répondre à ma propre question, mais il a obtenu:

m|(\w)\1+| 
+0

\ W est le contraire de ce que vous voulez, n'est-ce pas? – Telemachus

+0

Telemachus a raison, cela ne correspondra pas aux exemples que vous avez donnés dans la question. – gpojd

+0

Il est également préférable de ne pas utiliser de tuyaux (ou d'autres délimiteurs non définis par défaut) pour l'expression régulière, sauf si vous avez une raison de le faire. – Pat

1

C'est ce que sont les références arrières.

m/(\w)\1\1/ 

fera l'affaire.

+1

Cela ne correspondrait pas à 'aa'. – gpojd

3

Cela correspondra plus \ w serait, comme @@@:

/(.)\1+/ 
+0

Ceci est le bon, pour "une séquence du même caractère", et pas seulement les exemples "aaa", "bbb". +1 – Axeman

+0

Quelle est la différence entre l'insertion de l'expression dans les barres obliques "/" et leur non-utilisation? – skan

10

Notez que dans Perl 5.10, nous avons des notations alternatives pour ainsi des références arrières.

foreach (qw(aaa bbb abc)) { 
    say; 
    say ' original' if /(\w)\1+/; 
    say ' new way' if /(\w)\g{1}+/; 
    say ' relative' if /(\w)\g{-1}+/; 
    say ' named' if /(?'char'\w)\g{char}+/; 
    say ' named' if /(?<char>\w)\k<char>+/; 
} 
+0

http://perldoc.perl.org/perlre.html ou http://perldoc.perl.org/search.html?q=perlre –

1

Ceci est également possible en utilisant des expressions régulières pures (à savoir celles qui décrivent les langages réguliers - pas Perl regExps). Malheureusement, cela signifie une expression rationnelle dont la longueur est proportionnelle à la taille de l'alphabet, par exemple .:

(a* + b* + ... + z*) 

Où a ... z sont les symboles dans l'alphabet fini. Donc, les expressions rationnelles Perl, même si elles sont un surensemble d'expressions régulières pures, ont certainement leurs avantages même si vous voulez juste les utiliser pour des expressions régulières pures!

Questions connexes