re.match
est ancré au début de la chaîne. Cela n'a rien à voir avec les nouvelles lignes, donc ce n'est pas la même chose que d'utiliser^
dans le motif.
Comme documentation re.match dit la :
Si zéro ou plusieurs caractères au
début de la chaîne correspondent au modèle d'expression régulière, renvoyez unMatchObject
instance . RevenirNone
si la chaîne ne correspond pas au modèle; notez que ceci est différent d'une correspondance de longueur nulle.
Remarque: Si vous souhaitez rechercher une correspondance n'importe où dans la chaîne, utilisez search()
plutôt.
re.search
recherche la chaîne entière, comme le dit la documentation :
Parcourez la chaîne à la recherche d'un emplacement où le modèle d'expression régulière produit une correspondance et renvoyez une MatchObject
instance correspondante . Retourne None
si aucune position dans la chaîne ne correspond au motif; notez que cela diffère de la recherche d'une correspondance de longueur nulle à un moment donné de la chaîne.
Donc, si vous devez faire correspondre au début de la chaîne, ou faire correspondre l'utilisation de la chaîne entière match
. C'est plus rapide. Sinon, utilisez search
.
La documentation a une section spécifique pour match
vssearch
qui couvre également les chaînes multilignes:
Python propose deux opérations primitives différentes basées sur des expressions régulières: match
vérifie une correspondance
uniquement au début de la chaîne, tandis que search
vérifie une correspondance
n'importe où dans la chaîne (c'est ce que Perl fait par défaut).
Notez que cela match
peut différer de search
même lorsque vous utilisez une expression régulière commençant par '^'
: '^'
ne correspond qu'au début de la chaîne, ou en
MULTILINE
mode également immédiatement après une nouvelle ligne. L' match
opération « » réussit que si le motif correspond au début de la chaîne,
quel que soit le mode, ou à la position de départ donnée par l' pos
argument facultatif , que la nouvelle ligne la précède ou non.
Maintenant, assez parlé. Il est temps de voir un exemple de code:
# example code:
string_with_newlines = """something
someotherthing"""
import re
print re.match('some', string_with_newlines) # matches
print re.match('someother',
string_with_newlines) # won't match
print re.match('^someother', string_with_newlines,
re.MULTILINE) # also won't match
print re.search('someother',
string_with_newlines) # finds something
print re.search('^someother', string_with_newlines,
re.MULTILINE) # also finds something
m = re.compile('thing$', re.MULTILINE)
print m.match(string_with_newlines) # no match
print m.match(string_with_newlines, pos=4) # matches
print m.search(string_with_newlines,
re.MULTILINE) # also matches
match
plutôt que plus généralsearch
? c'est pour la vitesse?match
? Est-ce une manœuvre intelligente de semer les API avec des noms non intuitifs pour me forcer à lire la documentation? Je ne le ferai toujours pas! Rebelle!match
ressemble un peufaster
à la recherche lorsque vous utilisez la même expression régulière, mais votre exemple semble incorrect selon un test de performance: stackoverflow.com/questions/180986/…search
⇒ trouver quelque chose n'importe où dans la chaîne et renvoyer un objet match.match
⇒ trouver quelque chose au début de la chaîne et renvoyer un objet match.la source
re.search
recherche le motif dans toute la chaîne , alorsre.match
qu'il ne recherche pas le motif; s'il ne le fait pas, il n'a d'autre choix que de le faire correspondre au début de la chaîne.la source
fullmatch
en phyton 3.4)?Ce commentaire de @ivan_bilan sous la réponse acceptée ci-dessus m'a fait penser si un tel hack accélère réellement quelque chose, alors découvrons combien de tonnes de performances vous gagnerez vraiment.
J'ai préparé la suite de tests suivante:
J'ai fait 10 mesures (1M, 2M, ..., 10M mots) qui m'ont donné l'intrigue suivante:
Les lignes résultantes sont étonnamment (en fait pas si étonnamment) droites. Et la
search
fonction est (légèrement) plus rapide compte tenu de cette combinaison de motifs spécifique. La morale de ce test: évitez de suroptimiser votre code.la source
match
fonction est toujours plus rapide que lasearch
fonction si l'on compare la même expression régulière. Vous pouvez archiver votre script en comparantre.search('^python', word)
àre.match('python', word)
(oure.match('^python', word)
qui est le même mais plus facile à comprendre si vous ne lisez pas la documentation et ne semble pas affecter les performances)match
fonction est généralement plus rapide. Lematch
est plus rapide lorsque vous souhaitez effectuer une recherche au début de la chaîne, lesearch
plus rapide lorsque vous souhaitez effectuer une recherche tout au long de la chaîne. Ce qui correspond au bon sens. C'est pourquoi @ivan_bilan avait tort - il cherchaitmatch
tout au long de la chaîne. C'est pourquoi vous avez raison - vousmatch
cherchiez au début de la chaîne. Si vous n'êtes pas d'accord avec moi, essayez de trouver des expressions rationnelles carmatch
cela est plus rapidere.search('python', word)
et fait le même travail.re.match('python')
est légèrement plus rapide quere.match('^python')
. Ça doit être.match
fonction est un peu plus rapide si vous voulez chercher au début d'une chaîne (par rapport à utiliser lasearch
fonction pour trouver un mot au début d'une chaîne avecre.search('^python', word)
par exemple). Mais je trouve cela bizarre, si vous dites à lasearch
fonction de rechercher au début d'une chaîne, elle devrait être aussi rapide que lamatch
fonction.Vous pouvez vous référer à l'exemple ci-dessous pour comprendre le fonctionnement
re.match
et la recherche.re.match
reviendranone
, maisre.search
reviendraabc
.la source
La différence est,
re.match()
induit en erreur toute personne habituée à l' appariement des expressions régulières Perl , grep ou sed , etre.search()
ne le fait pas. :-)Plus sobrement, comme le fait remarquer John D. Cook ,
re.match()
"se comporte comme si chaque modèle avait ^ précédé". En d'autres termes,re.match('pattern')
est égal àre.search('^pattern')
. Il ancre donc le côté gauche d'un motif. Mais il n'ancre pas non plus le côté droit d'un motif: cela nécessite toujours une terminaison$
.Franchement, compte tenu de ce qui précède, je pense qu'il
re.match()
devrait être déconseillé. Je serais intéressé de connaître les raisons pour lesquelles il devrait être conservé.la source
re.match tente de faire correspondre un modèle au début de la chaîne . re.search tente de faire correspondre le modèle dans la chaîne jusqu'à ce qu'il trouve une correspondance.
la source
Plus court:
search
balaye toute la chaîne.match
analyse uniquement le début de la chaîne.Ex suivant le dit:
la source