2009-04-16 7 views
3

J'ai quelques adresses e-mail, '[email protected]' et '[email protected]'.Différence de comportement regex entre Perl et Python?

En perl, je pourrais prendre la ligne To: d'un email brut et trouver l'une des adresses ci-dessus avec

/\[email protected](tickets\.)?company\.com/i 

En python, j'ai simplement écrit le regex ci-dessus comme '\[email protected](tickets\.)?company\.com' attendant le même résultat. Cependant, [email protected] n'est pas trouvé du tout et un findall sur le second renvoie une liste contenant seulement 'tickets.'. Donc clairement le '(tickets\.)?' est la zone de problème, mais quelle est exactement la différence dans les règles d'expression régulière entre Perl et Python qui me manque?

+0

Que diriez-vous du code? – Gumbo

Répondre

7

La documentation re.findall:

findall(pattern, string, flags=0) 
    Return a list of all non-overlapping matches in the string. 

    If one or more groups are present in the pattern, return a 
    list of groups; this will be a list of tuples if the pattern 
    has more than one group. 

    Empty matches are included in the result. 

Depuis (tickets\.) est un groupe, findall rendements au lieu du match. Si vous voulez tout le match, mettez un groupe autour du modèle entier et/ou utiliser des allumettes non-regroupement, à savoir

r'(\[email protected](tickets\.)?company\.com)' 
r'\[email protected](?:tickets\.)?company\.com' 

Notez que vous devrez choisir le premier élément de chaque tuple retourné par findall dans le premier cas.

+0

D'accord, mais intéressant, pas * évident *. – Axeman

2

Deux problèmes sautent me:

  1. Vous devez utiliser une chaîne brute pour éviter d'avoir à échapper « \ »
  2. Vous devez échapper « . »

Donc, essayez :

r'\[email protected](tickets\.)?company\.com' 

EDIT

Exemple de sortie:

>>> import re 
>>> exp = re.compile(r'\[email protected](tickets\.)?company\.com') 
>>> bool(exp.match("[email protected]")) 
True 
>>> bool(exp.match("[email protected]")) 
True 
+0

Je seconde cette suggestion. –

+0

# 2 est juste moi étant un newb à stackoverflow. Correction du message initial. ;) –

4

Je pense que le problème est dans vos attentes de valeurs extraites. Essayez d'utiliser dans votre code Python actuel:

'(\[email protected](?:tickets\.)?company\.com)' 
1

Il n'y a pas de différence dans les expressions rationnelles, mais il y a une différence dans ce que vous recherchez. Votre regex ne capture que "tickets." s'il existe dans les deux expressions régulières. Vous voulez probablement quelque chose comme ça

#!/usr/bin/python 

import re 

regex = re.compile("(\[email protected](?:tickets\.)?company\.com)"); 

a = [ 
    "[email protected]", 
    "[email protected]", 
    "[email protected]", 
    "[email protected]" 
]; 

for string in a: 
    print regex.findall(string) 
Questions connexes