Re.search और re.match के बीच क्या अंतर है?


526

पायथन मॉड्यूल में search()और match()कार्यों के बीच क्या अंतर है ?re

मैंने प्रलेखन ( वर्तमान प्रलेखन ) पढ़ा है , लेकिन मुझे यह याद नहीं है। मैं इसे देखता रहा और इसे फिर से सीखता रहा। मैं उम्मीद कर रहा हूं कि कोई व्यक्ति इसे स्पष्ट रूप से उदाहरणों के साथ जवाब देगा ताकि (शायद) यह मेरे सिर में चिपक जाएगा। या कम से कम मेरे पास अपने सवाल के साथ लौटने के लिए एक बेहतर जगह होगी और इसे फिर से सीखने में कम समय लगेगा।

जवाबों:


508

re.matchस्ट्रिंग की शुरुआत में लंगर डाला गया है। इसका newlines से कोई लेना-देना नहीं है, इसलिए यह ^पैटर्न में उपयोग करने के समान नहीं है ।

जैसा कि re.match प्रलेखन कहता है:

यदि स्ट्रिंग की शुरुआत में शून्य या अधिक वर्ण नियमित अभिव्यक्ति पैटर्न से मेल खाते हैं, तो इसी MatchObjectउदाहरण को वापस करें । Noneयदि स्ट्रिंग पैटर्न से मेल नहीं खाती है तो वापस लौटें ; ध्यान दें कि यह एक शून्य-लंबाई मैच से अलग है।

नोट: यदि आप स्ट्रिंग में कहीं भी मैच का पता लगाना चाहते हैं, तो search() इसके बजाय उपयोग करें ।

re.searchसंपूर्ण स्ट्रिंग खोजता है, जैसा कि दस्तावेज़ कहता है :

स्ट्रिंग के माध्यम से स्कैन एक ऐसे स्थान की तलाश में जहां नियमित अभिव्यक्ति पैटर्न एक मैच का निर्माण करता है, और इसी MatchObjectउदाहरण को वापस लौटाता है । Noneस्ट्रिंग में कोई स्थिति पैटर्न से मेल खाती है तो वापस लौटें ; ध्यान दें कि यह स्ट्रिंग में कुछ बिंदु पर एक शून्य-लंबाई मैच खोजने से अलग है।

तो अगर आपको स्ट्रिंग की शुरुआत में मिलान करने की आवश्यकता है, या पूरे स्ट्रिंग उपयोग से मिलान करने की आवश्यकता है match। यह तेज है। अन्यथा उपयोग करें search

दस्तावेज़ीकरण में बनाम के लिएmatchsearch एक विशिष्ट खंड होता है जिसमें बहुस्तरीय तार भी शामिल होते हैं:

पायथन नियमित अभिव्यक्ति के आधार पर दो अलग-अलग आदिम संचालन प्रदान matchकरता है : केवल स्ट्रिंग की शुरुआत में searchएक मैच की जांच करता है , जबकि स्ट्रिंग में कहीं भी एक मैच की जांच करता है (यह वही है जो पर्ल डिफ़ॉल्ट रूप से करता है)।

ध्यान दें कि एक नियमित अभिव्यक्ति का उपयोग करते समय भी matchइससे भिन्न हो सकते हैं : केवल स्ट्रिंग की शुरुआत में मेल खाता है, या मोड में भी तुरंत एक नई पंक्ति का अनुसरण करता है। " " ऑपरेशन सफल होता है पर केवल तभी पैटर्न मैचों शुरू स्ट्रिंग के मोड की परवाह किए बिना, या वैकल्पिक द्वारा दिए गए प्रारंभिक स्थिति में है कि क्या एक नई पंक्ति पछाड़ यह की परवाह किए बिना तर्क।search'^''^'MULTILINEmatchpos

अब, पर्याप्त बात करते हैं। कुछ उदाहरण कोड देखने का समय:

# 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

नए तार वाले तार के बारे में क्या?
डेरिल स्पिट्जर

25
कोई matchभी अधिक सामान्य के बजाय सीमित का उपयोग क्यों करेगा search? क्या यह गति के लिए है?
अलबी

13
@ एलबी का मैच खोज की तुलना में बहुत तेज है, इसलिए आप regex.search ("शब्द") करने के बजाय आप regex.match ((। *?) शब्द (। *?)) कर सकते हैं और यदि आप काम कर रहे हैं तो प्रदर्शन का लाभ प्राप्त करें। लाखों नमूने।
ivan_bilan

19
खैर, यह नासमझ है। इसे क्यों कहते हैं match? क्या यह एक चतुर पैंतरेबाज़ी है जिसे एपीआई के बीजक नाम के साथ मुझे दस्तावेज़ पढ़ने के लिए मजबूर करना है? मैं अभी भी यह नहीं करेंगे! बागी!
समरॉन

1
@ivan_bilan समान नियमित अभिव्यक्ति का उपयोग करते समय खोज की तुलना में matchथोड़ा सा दिखता है, fasterलेकिन आपका उदाहरण एक प्रदर्शन परीक्षण के अनुसार गलत लगता है: stackoverflow.com/questions/180986/…
baptx

101

search ⇒ स्ट्रिंग में कहीं भी कुछ खोजो और मैच ऑब्जेक्ट लौटाओ।

match⇒ स्ट्रिंग की शुरुआत में कुछ ढूंढें और एक मैच ऑब्जेक्ट वापस करें।


49

re.search स्ट्रिंग के दौरान पैटर्न के लिए खोज करें , जबकि पैटर्न की खोज नहींre.match करता है ; यदि यह नहीं है, तो यह स्ट्रिंग की शुरुआत में इसे मैच करने के अलावा और कोई विकल्प नहीं है ।


5
शुरुआत में मैच क्यों, लेकिन स्ट्रिंग के अंत तक ( fullmatchफाइटन 3.4 में) नहीं?
स्मित जॉन्थ

49

मैच खोज की तुलना में बहुत तेज़ है, इसलिए regex.search ("शब्द") करने के बजाय आप लाखों लोगों के साथ काम कर रहे हैं, तो आप regexatch ((? *?) शब्द (?)?) का उपयोग कर सकते हैं और बहुत अधिक प्रदर्शन प्राप्त कर सकते हैं। नमूने हैं।

ऊपर दिए गए स्वीकृत उत्तर के तहत @ivan_bilan की इस टिप्पणी से मुझे लगा कि अगर इस तरह की हैकिंग वास्तव में कुछ भी तेज़ कर रही है, तो आइए जानें कि वास्तव में आपको कितने टन का प्रदर्शन मिलेगा।

मैंने निम्नलिखित परीक्षण सूट तैयार किया:

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)

मैंने 10 माप किए (1M, 2M, ..., 10M शब्द) जिसने मुझे निम्नलिखित कथानक दिए:

मैच बनाम खोज रेगेक्स स्पीडटेस्ट लाइन प्लॉट

परिणामी रेखाएं आश्चर्यजनक रूप से (वास्तव में आश्चर्यजनक रूप से नहीं) सीधी हैं। और searchफ़ंक्शन इस विशिष्ट पैटर्न संयोजन को देखते हुए तेजी से (थोड़ा) है । इस परीक्षण का नैतिक: अपने कोड को अपनाने से बचें।


11
+1 वास्तव में एक बयान के पीछे की धारणाओं की जांच करने के लिए जिसका अर्थ अंकित मूल्य पर लिया जाना है - धन्यवाद।
रॉबर्ट डोडिएर

वास्तव में @ivan_bilan की टिप्पणी गलत लगती है लेकिन यदि आप उसी नियमित अभिव्यक्ति की तुलना करते हैं, तो फ़ंक्शन matchअभी भी फ़ंक्शन से तेज है search। आप की तुलना करके अपने लिपि में जाँच कर सकते हैं re.search('^python', word)करने के लिए re.match('python', word)(या re.match('^python', word)जो एक ही है, लेकिन समझने के लिए यदि आप दस्तावेज़ पढ़ नहीं है आसान है और प्रदर्शन को प्रभावित करने के लिए नहीं लगता है)
baptx

@ बपतिस्मा मैं इस कथन से असहमत हूं कि matchसमारोह आम तौर पर तेज है। matchतेजी से जब आप खोज करना चाहते है शुरुआत में स्ट्रिंग की, searchतेजी से होता है जब आप खोज करना चाहते भर स्ट्रिंग। जो सामान्य ज्ञान से मेल खाती है। इसलिए @ivan_bilan गलत था - वह matchपूरे तार में खोज करता था। इसलिए आप सही हैं - आप matchस्ट्रिंग की शुरुआत में खोज करते थे। यदि आप मुझसे असहमत हैं, तो इसके लिए रेगेक्स ढूंढने की कोशिश करें, matchजो तेजी से हो re.search('python', word)और वही काम करे।
जेजेकोमोन

इसके अलावा @baptx, एक फुटनोट के रूप में, re.match('python') है मामूली तेजी से re.match('^python')। इसे होना चाहिए।
ज्येकोमन

@ जेकॉमोमन हां, मेरा यही मतलब है, matchयदि आप एक स्ट्रिंग की शुरुआत में खोज करना चाहते हैं , तो फ़ंक्शन थोड़ा तेज है ( उदाहरण के लिए searchएक स्ट्रिंग की शुरुआत में एक शब्द खोजने के लिए फ़ंक्शन का उपयोग करने की तुलना में re.search('^python', word))। लेकिन मुझे यह अजीब लगता है, यदि आप searchफ़ंक्शन को स्ट्रिंग की शुरुआत में खोज करने के लिए कहते हैं, तो यह matchफ़ंक्शन के समान तेज़ होना चाहिए ।
बपतिस्मा

31

आप नीचे दिए गए उदाहरण उल्लेख कर सकते हैं की कार्यप्रणाली को समझने के लिए re.matchऔर re.search

a = "123abc"
t = re.match("[a-z]+",a)
t = re.search("[a-z]+",a)

re.matchलौटेंगे none, लेकिन re.searchलौटेंगे abc


3
केवल उस खोज को जोड़ना चाहेंगे जो _sre.SRE_Match ऑब्जेक्ट को वापस लौटाएगी (या यदि नहीं मिली तो कोई नहीं)। 'एबीसी' पाने के लिए, आपको
SanD

30

अंतर यह है re.match()कि पर्ल , grep , या sed नियमित अभिव्यक्ति मिलान के आदी किसी को भी भ्रमित re.search()करता है , और नहीं करता है। :-)

अधिक स्पष्ट रूप से , जैसा कि जॉन डी। कुक टिप्पणी करते हैं , re.match()"ऐसा व्यवहार करता है मानो प्रत्येक पैटर्न में ^ पूर्वसर्ग है।" दूसरे शब्दों में, re.match('pattern')बराबर re.search('^pattern')। तो यह एक पैटर्न के बाईं ओर लंगर डालता है। लेकिन यह भी एक पैटर्न के दाईं ओर लंगर नहीं करता है: कि अभी भी एक समाप्ति की आवश्यकता है $

सच कहूँ तो ऊपर दिया गया, मुझे लगता है कि re.match()पदावनत होना चाहिए। मुझे यह जानने के लिए दिलचस्पी होगी कि इसे बरकरार रखा जाए।


4
"ऐसा व्यवहार करता है मानो हर पैटर्न में ^ प्रीपेंडेड है।" केवल तभी सत्य है जब आप मल्टीलाइन विकल्प का उपयोग नहीं करते हैं। सही कथन है "... has a Appended"
जोएलफैन

14

स्ट्रिंग की शुरुआत में एक पैटर्न से मेल खाने का प्रयास करते हैं । re.search तब तक स्ट्रिंग से पूरे पैटर्न का मिलान करने का प्रयास करता है जब तक कि वह एक मैच नहीं पाता।


3

बहुत कम:

  • search पूरे स्ट्रिंग के माध्यम से स्कैन करता है।

  • match केवल स्ट्रिंग की शुरुआत को स्कैन करता है।

निम्नलिखित पूर्व कहते हैं:

>>> a = "123abc"
>>> re.match("[a-z]+",a)
None
>>> re.search("[a-z]+",a)
abc
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.