Quelle est la différence entre re.search et re.match?
Question
Quelle est la différence entre les fonctions search ()
et match ()
dans les fonctions module Python concernant
?
J'ai lu la documentation (< a href = "http://docs.python.org/2/library/re.html?highlight=matching%20searching#search-vs-match" rel = "noreferrer"> documentation actuelle ), mais je ne semble jamais s'en souvenir. Je continue à avoir à le chercher et à le réapprendre. J'espère que quelqu'un y répondra clairement par des exemples afin que (peut-être) cela me reste dans la tête. Ou du moins, ma question me permettra de revenir plus facilement et il faudra moins de temps pour la réapprendre.
La solution
re.match
est ancré au début de la chaîne. Cela n’a rien à voir avec les retours à la ligne, ce n’est donc pas la même chose que d’utiliser ^
dans le modèle.
Comme la documentation re.match dit:
Si zéro ou plus de caractères à la le début de la chaîne correspond au modèle d'expression régulière, renvoie un instance
MatchObject
correspondante. RenvoieAucun
si la chaîne ne le permet pas. faire correspondre le motif; notez que c'est différent d’un match nul.Remarque: si vous souhaitez localiser une correspondance n'importe où dans la chaîne, utilisez
search ()
à la place.
re.search
recherche dans la chaîne entière, comme la documentation dit :
Parcourez la chaîne à la recherche d'un endroit où l'expression régulière motif produit une correspondance et retourne un instance
MatchObject
correspondante. RenvoieAucun
si aucune position dans la la chaîne correspond au motif; Notez que c'est différent de trouver un match zéro longueur à un moment donné dans la chaîne.
Donc, si vous devez faire une correspondance au début de la chaîne, ou utiliser toute la chaîne, utilisez match
. C'est plus rapide. Sinon, utilisez search
.
La documentation a une section spécifique pour correspond
vs. recherche
qui couvre également les chaînes multilignes:
Python propose deux primitives différentes opérations basées sur des expressions:
match
recherche une correspondance uniquement au début de la chaîne, pendant quesearch
recherche une correspondance n'importe où dans la chaîne (c'est ce que Perl le fait par défaut).Notez que la correspondance
peut différer de
recherche
même en utilisant une expression régulière commençant par'^'
:'^'
correspond uniquement au début de la chaîne, ou dans ModeMULTILINE
également immédiatement suite à une nouvelle ligne. La & # 8220;correspondance
& # 8221; opération réussit seulement si le motif correspond au début de la chaîne quel que soit le mode ou au départ position donnée par l'optionpos
argument indépendamment de si un la nouvelle ligne le précède.
Maintenant, assez de paroles. 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
Autres conseils
rechercher
? rechercher quelque chose n'importe où dans la chaîne et retourner un objet correspondant.
match
? trouvez quelque chose au début de la chaîne et renvoyez un objet match.
re.search
rechercher le motif dans la chaîne , alors que re.match
effectue ne pas rechercher le motif; Si ce n'est pas le cas, il n'a pas d'autre choix que de la faire correspondre au début de la chaîne.
vous pouvez vous référer à l'exemple ci-dessous pour comprendre le fonctionnement de re.match et de re.search
a = "123abc"
t = re.match("[a-z]+",a)
t = re.search("[a-z]+",a)
re.match ne renverra rien, mais re.search retournera abc.
La différence est que re.match ()
trompe quiconque est habitué à Perl , grep ou sed correspondance d'expression régulière et re.search ()
ne le fait pas. : -)
Plus sobrement, Comme le fait remarquer John D. Cook , re.match ( )
"se comporte comme si chaque motif était précédé de ^." En d'autres termes, re.match ('pattern')
est égal à re.search ('^ pattern')
. Donc, il ancre le côté gauche d'un motif. Mais cela n'ancre pas non plus le côté droit d'un motif: qui nécessite toujours un $
final.
Franchement, vu ce qui précède, je pense que re.match ()
devrait être obsolète. Je serais intéressé de connaître les raisons pour lesquelles il devrait être maintenu.
La correspondanceest beaucoup plus rapide que la recherche. Par conséquent, au lieu de faire regex.search ("mot"), vous pouvez faire regex.match ((. *?) mot (. *?)) et gagner des tonnes de performances si vous êtes travailler avec des millions d'échantillons.
Ce commentaire de @ivan_bilan sous le réponse acceptée ci-dessus m'a fait réfléchir si un tel hack accélère réellement quoi que ce soit, voyons donc combien de tonnes de performances vous gagnerez réellement.
J'ai préparé la suite de tests suivante:
import random
import re
import string
import time
LENGTH = 10
LIST_SIZE = 1000000
def generate_word():
word = [random.choice(string.ascii_lowercase) for _ in range(LENGTH)]
word = ''.join(word)
return word
wordlist = [generate_word() for _ in range(LIST_SIZE)]
start = time.time()
[re.search('python', word) for word in wordlist]
print('search:', time.time() - start)
start = time.time()
[re.match('(.*?)python(.*?)', word) for word in wordlist]
print('match:', time.time() - start)
J'ai fait 10 mesures (mots 1M, 2M, ..., 10M) qui m'ont donné l'intrigue suivante:
Les lignes résultantes sont étonnamment droites (en fait pas si surprenant). Et la fonction search
est (légèrement) plus rapide étant donné cette combinaison de modèle spécifique. La morale de ce test: Évitez d’optimiser votre code.
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 tout au long de la chaîne jusqu'à ce qu'il trouve une correspondance.
Beaucoup plus court:
-
search
analyse toute la chaîne. -
correspondance
Ne fait que le début de la chaîne.
Après Ex le dit:
>>> a = "123abc"
>>> re.match("[a-z]+",a)
None
>>> re.search("[a-z]+",a)
abc