2010-12-03 8 views
6

je besoin d'une expression régulière pour correspondre une chaîne:Est-ce que cela peut être fait dans une regex?

  • a que des chiffres 0-9 et espaces
  • tous les chiffres doivent être identiques
  • devrait avoir au-moins 2 chiffres
  • doit commencer et se terminer par chiffres

Correspondances:

 
11 
11111 
1 1 1 1 1 
1 1 
11 1 1 1 1 1 
1   1 
1 1  1 

Aucun résultat:

 
1    has only one digit 
11111   has space at the end 
11111  has space at beginning 
12   digits are different 
11:   has other character 

Je sais regex pour chacun de mes besoins. De cette façon, je vais utiliser 4 tests regex . Pouvons-nous le faire dans une regex?

+0

Qu'est-ce que le processeur et la langue regex utilisez-vous? –

Répondre

14

Oui, il peut être fait dans un regex:

^(\d)(?:\1|)*\1$ 

Rubular link

Explication:

^  - Start anchor 
(  - Start parenthesis for capturing 
\d - A digit 
)  - End parenthesis for capturing 
(?: - Start parenthesis for grouping only 
\1  - Back reference referring to the digit capture before 
|  - Or 
     - A literal space 
)  - End grouping parenthesis 
*  - zero or more of previous match 
\1  - The digit captured before 
$  - End anchor 
+1

Dans le cas où cela n'est pas évident, \ 1 jusqu'à \ 9 se réfère à la valeur du bloc correspondant, ordonnée par l'ouverture des parenthèses - elles sont appelées * backreferences * et sont supportées dans la plupart des moteurs d'expressions régulières – Gareth

+1

cela fait ce que vous pensez qu'il fait: que '\ 1' dans la classe de caractères n'est pas un backref, mais un Control-A. – tchrist

+2

@Gareth: Pas dans les classes de caractères, ils ne le font pas! – tchrist

2

Tenir compte de ce programme:

#!/usr/bin/perl -l 
$_ = "3 33 3 3"; 
print /^(\d)[\1 ]*\1$/  ? 1 : 0; 
print /^(\d)(?:\1|)*\1$/ ? 1 : 0; 

Il produit la sortie

0 
1 

La réponse est évidente quand on regarde les expressions rationnelles compilées:

perl -c -Mre=debug /tmp/a 
Compiling REx "^(\d)[\1 ]*\1$" 
synthetic stclass "ANYOF[0-9][{unicode_all}]". 
Final program: 
    1: BOL (2) 
    2: OPEN1 (4) 
    4: DIGIT (5) 
    5: CLOSE1 (7) 
    7: STAR (19) 
    8: ANYOF[\1 ][] (0) 
    19: REF1 (21) 
    21: EOL (22) 
    22: END (0) 
floating ""$ at 1..2147483647 (checking floating) stclass ANYOF[0-9][{unicode_all}] anchored(BOL) minlen 1 
Compiling REx "^(\d)(?:\1|)*\1$" 
synthetic stclass "ANYOF[0-9][{unicode_all}]". 
Final program: 
    1: BOL (2) 
    2: OPEN1 (4) 
    4: DIGIT (5) 
    5: CLOSE1 (7) 
    7: CURLYX[1] {0,32767} (17) 
    9: BRANCH (12) 
    10:  REF1 (16) 
    12: BRANCH (FAIL) 
    13:  EXACT < > (16) 
    15: TAIL (16) 
    16: WHILEM[1/1] (0) 
    17: NOTHING (18) 
    18: REF1 (20) 
    20: EOL (21) 
    21: END (0) 
floating ""$ at 1..2147483647 (checking floating) stclass ANYOF[0-9][{unicode_all}] anchored(BOL) minlen 1 
/tmp/a syntax OK 
Freeing REx: "^(\d)[\1 ]*\1$" 
Freeing REx: "^(\d)(?:\1|)*\1$" 

Backrefs ne sont que des personnages octal réguliers à l'intérieur des classes de caractères !!

+0

Vous ne pouvez pas utiliser \ 1 dans [], testez-le: print 'Votre solution =', '2 2 2' = ~/^ (\ d) [\ 1] * \ 1 $ /? "Vrai": "Faux", "\ n"; print 'Mine solution =', '2 2 2' = ~/^ (\ d) (\ 1 |) * \ 1 $ /? "Vrai": "Faux", "\ n"; –

+0

@ xt.and.r: Bien sûr que vous ne pouvez pas. C'était mon point. Je n'utilise pas '\ 1' dans' [] '. C'est ce que j'essayais de faire voir aux gens. – tchrist

+0

Ok :) et "?:" N'est pas requis. :) –

1
^(\d)(*\1)+$ 


+0

Simplement:^(\ d) (* \ 1) + $ –

0
/^(\d)(\1|)*\1$/ 
Questions connexes