Dans une expression régulière Python, je rencontre ce problème singulier. Pourriez-vous donner des instructions sur les différences entre re.findall('(ab|cd)', string)
et re.findall('(ab|cd)+', string)
?
import re
string = 'abcdla'
result = re.findall('(ab|cd)', string)
result2 = re.findall('(ab|cd)+', string)
print(result)
print(result2)
La sortie réelle est:
['ab', 'cd']
['cd']
Je ne sais pas pourquoi le deuxième résultat ne contient pas 'ab'
aussi bien?
Réponses:
+
est un quantificateur de répétition qui correspond une ou plusieurs fois. Dans l'expression régulière(ab|cd)+
, vous répétez le groupe de capture à l'(ab|cd)
aide de +. Cela ne capturera que la dernière itération.Vous pouvez raisonner à propos de ce comportement comme suit:
Dites que votre chaîne est
abcdla
et regex l'est(ab|cd)+
. Le moteur Regex trouvera une correspondance pour le groupe entre les positions 0 et 1 au furab
et à mesure qu'il quitte le groupe de capture. Ensuite, il voit le+
quantificateur et essaie donc de capturer à nouveau le groupe et captureracd
entre les positions 2 et 3.Si vous souhaitez capturer toutes les itérations, vous devez plutôt capturer le groupe extensible avec
((ab|cd)+)
lequel correspondabcd
etcd
. Vous pouvez faire en sorte que le groupe interne ne soit pas capturé car nous ne nous soucions pas des correspondances de groupe interne avec((?:ab|cd)+)
quelles correspondancesabcd
https://www.regular-expressions.info/captureall.html
Depuis les documents,
la source
'(?:ab|cd)+'
va marcher.Je ne sais pas si cela clarifiera davantage les choses, mais essayons d'imaginer ce qui se passe sous le capot d'une manière simple, nous allons résumer ce qui se passe en utilisant match
findall
correspondre et consommer la chaîne en même temps imaginons ce qui se passe avec ce REGEX'(ab|cd)'
:Maintenant, la même chose avec
'(ab|cd)+'
J'espère que cela clarifie un peu les choses.
la source
Donc, pour moi, une partie déroutante était le fait que
docs
il ne vous renvoie donc pas une correspondance complète, mais uniquement une correspondance de capture. Si vous faites en sorte que ce groupe ne capture pas
(re.findall('(?:ab|cd)+', string)
, il reviendra["abcd"]
comme je m'y attendais initialementla source