RegEx

2010-01-14 5 views
2

Avoir Les références arrières l'expression régulière suivante:RegEx

([a-z])([0-9])\1 

Il correspond a5a, est-il possible pour qu'il corresponde aussi a5b, a5c, a5d et ainsi de suite?


EDIT: D'accord, je comprends que je pouvais utiliser ([a-z])([0-9])([a-z]) mais j'ai une très longue et compliquée expression régulière (correspondant à sous-sous-sous domaines -...- ou correspondant une adresse IPv4) qui bénéficierait vraiment du comportement décrit ci-dessus. Est-ce que c'est en quelque sorte possible de réaliser avec backreferences ou toute autre chose?


Anon. answer est ce que je dois, mais il semble être erroné.

Répondre

2

Vous n'avez pas besoin de références arrière si la deuxième lettre est indépendante de la première, n'est-ce pas?

([a-z])([0-9])([a-z])+ 

EDIT

Si vous ne voulez pas répéter la dernière partie encore et encore, puis:

([a-z])([0-9])([a-z]) 

Juste enlever le '+'.

+0

Merci Bran, mais s'il vous plaît vérifier ma modification. –

+0

Non, je veux avoir l'effet de la première regex que vous avez fournie '([a-z]) ([0-9]) ([a-z]) +' mais sans avoir à répéter la dernière partie encore et encore. –

0

Je ne suis pas votre question?

[a-z][0-9][a-z] Exactly 1 
[a-z][0-9][a-z]? One or 0 
[a-z][0-9][a-z]+ 1 or more 
[a-z][0-9][a-z]* 0 or more 
+0

Pouvez-vous s'il vous plaît vérifier ma modification? Merci. –

2

Le point entier d'un back-référence dans une expression régulière est de faire correspondre la même chose que la sous-expression indiquée, donc il n'y a aucun moyen de désactiver ce comportement.

Pour obtenir le comportement souhaité, de pouvoir réutiliser ultérieurement une partie d'une expression régulière, vous pouvez simplement définir les parties de l'expression régulière que vous souhaitez réutiliser dans une chaîne séparée, et (en fonction de la langue travaillez dans) utilisez l'interpolation de chaîne ou la concaténation pour construire l'expression régulière à partir des pièces.

Par exemple, dans Ruby:

>> letter = '([a-z])' 
=> "([a-z])" 
>> /#{letter}([0-9])#{letter}+/ =~ "a5b" 
=> 0 
>> /#{letter}([0-9])#{letter}+/ =~ "a51" 
=> nil 

Ou en JavaScript:

var letter = '([a-z])'; 
var re = new RegExp(letter + '([0-9])' + letter + '+'); 
"a5b".match(re) 
1

Je soupçonne que vous vouloir quelque chose de similaire à la construction Perl (?PARNO) (ce n'est pas seulement pour récursion;).

/([a-z])([0-9])(?1)+/ 

va correspondre à ce que vous voulez - et tout changement au premier groupe de capture sera reflété dans ce que les (?1) matches.

+0

Semble être ce que je cherche cependant l'expression rationnelle que vous avez fournie me donne des erreurs dans RegexBuddy (en mode PCRE et Perl). –

+0

Fonctionne dans ma version de Perl. –

+0

La partie '(? 1)' de la regex me donne l'erreur suivante dans RegexBuddy en mode Perl: ** Caractères erronés (éventuellement jeton regex incomplet ou métacaractères non échappés) **, merci quand même. =) –

3

La réponse est pas avec des backreferences

backreference signifie correspondre à la valeur qui a été déjà mise en correspondance. Cela ne signifie pas correspondre à l'expression précédente.Mais si votre langage le permet, vous pouvez substituer une variable dans une chaîne dans votre expression avant de la compiler.

Tcl:

set exp1 "([a-z])" 
regexp "${exp1}([0-9])${exp1}+" $string 

Javascript:

var exp1 = '([a-z])'; 
var regexp = new RegExp(exp1 + '([0-9])' + exp1 + '+'); 
string.match(regexp); 

Perl:

my $exp1 = '([a-z])'; 
$string =~ /${exp1}([0-9])${exp1}+/; 
0

sont pour récupérer références arrières les données de plus tôt dans l'expression rationnelle et de l'utiliser plus tard. Ils ne sont pas pour résoudre les problèmes de style. Une regex avec backreferences ne fonctionnera pas comme une sans. Vous pourriez juste devoir vous habituer à regexes étant répétitif et moche.

Essayez peut-être Python, ce qui facilite la création de regex à partir de blocs plus petits. Pas clair si vous êtes autorisé à changer votre environnement ... vous êtes chanceux d'avoir des références arrières en premier lieu.