পুনঃ অনুসন্ধান এবং পুনরায় ম্যাচের মধ্যে পার্থক্য কী?


526

পাইথন মডিউলটিতেsearch() এবং match()কার্যের মধ্যে পার্থক্য কী ?re

আমি ডকুমেন্টেশন ( বর্তমান ডকুমেন্টেশন ) পড়েছি , তবে আমি কখনই এটি মনে করি না। আমি এটি সন্ধান করতে এবং এটি পুনরায় শিখতে থাকি। আমি আশা করছি যে কেউ উদাহরণ সহ পরিষ্কারভাবে এর উত্তর দেবেন যাতে (সম্ভবত) এটি আমার মাথায় লেগে থাকবে। বা কমপক্ষে আমার প্রশ্নটি নিয়ে আমার ফিরে আসার জন্য আরও ভাল জায়গা থাকবে এবং এটি পুনরায় শেখাতে কম সময় লাগবে।

উত্তর:


508

re.matchস্ট্রিংয়ের শুরুতে নোঙ্গর করা হয়। নিউলাইনগুলির সাথে এর কোনও যোগসূত্র নেই, তাই এটি ^প্যাটার্নটিতে ব্যবহারের মতো নয় ।

Re.match ডকুমেন্টেশন যেমন বলে:

স্ট্রিংয়ের শুরুতে যদি শূন্য বা আরও বেশি অক্ষরগুলি নিয়মিত প্রকাশের প্যাটার্নের সাথে মেলে, তবে কোনও অনুচ্ছেদে ফিরে MatchObjectআসুন। Noneস্ট্রিংটি প্যাটার্নের সাথে মেলে না তবে ফিরে আসুন ; মনে রাখবেন এটি শূন্য দৈর্ঘ্যের ম্যাচ থেকে আলাদা।

দ্রষ্টব্য: আপনি যদি কোনও ম্যাচ স্ট্রিংয়ে সনাক্ত করতে চান তবে search() পরিবর্তে ব্যবহার করুন।

re.searchডকুমেন্টেশন যেমন বলেছে , পুরো স্ট্রিংটি অনুসন্ধান করে :

স্ট্রিংয়ের মাধ্যমে স্ক্যান করে এমন কোনও অবস্থানের সন্ধান করুন যেখানে নিয়মিত প্রকাশের প্যাটার্নটি একটি মিল তৈরি করে এবং এর সাথে সম্পর্কিত MatchObjectউদাহরণটি ফেরত দেয় । Noneস্ট্রিংয়ের কোনও অবস্থান যদি প্যাটার্নের সাথে মেলে না তবে ফিরে আসুন ; নোট করুন যে স্ট্রিংয়ের কোনও এক সময়ে শূন্য দৈর্ঘ্যের ম্যাচটি খুঁজে পাওয়া থেকে আলাদা।

সুতরাং আপনার যদি স্ট্রিংয়ের শুরুতে মেলানো দরকার বা পুরো স্ট্রিং ব্যবহারের সাথে মেলে match। এটি দ্রুত। অন্যথায় ব্যবহার search

ডকুমেন্টেশনে বনামের জন্যmatchsearch একটি নির্দিষ্ট বিভাগ রয়েছে যা মাল্টলাইন স্ট্রিংগুলিও কভার করে:

: পাইথন অফার দুটি ভিন্ন আদিম অপারেশন রেগুলার এক্সপ্রেশনের উপর ভিত্তি করে matchএকটি ম্যাচের জন্য চেক শুধুমাত্র শুরুতে যখন স্ট্রিং এর, searchএকটি ম্যাচের জন্য চেক যে কোন জায়গায় স্ট্রিং (এই পার্ল ডিফল্টরূপে কি যায়)।

নোট যেটি নিয়মিত অভিব্যক্তিটি দিয়ে শুরু করার সাথে matchপৃথক হতে পারে : কেবল স্ট্রিংয়ের শুরুতে বা মোডে তাত্ক্ষণিকভাবে একটি নতুন লাইন অনুসরণ করার পরেও মেলে । মোড নির্বিশেষে স্ট্রিংয়ের শুরুতে প্যাটার্নটি মিলে গেলে বা lineচ্ছিক যুক্তি দিয়ে শুরু করা অবস্থানে কোনও নিউলাইন এর আগে রয়েছে কিনা নির্বিশেষে " " অপারেশনটি সফল হয় ।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? এটা কি গতির জন্য?
Alby

13
@ অ্যালবাই ম্যাচটি অনুসন্ধানের চেয়ে অনেক দ্রুত, সুতরাং আপনি regex.search ("শব্দ") না করে আপনি regex.match ((। *?) শব্দ (। *?)) করতে পারেন এবং আপনি যদি কাজ করে থাকেন তবে প্রচুর পারফরম্যান্স অর্জন করতে পারবেন লক্ষ লক্ষ নমুনা।
আইভান_বিলান

19
আচ্ছা, এটা বোকা। কেন ডাকবে match? আমাকে ডকুমেন্টেশন পড়তে বাধ্য করার জন্য অপরিশোধিত নামগুলির সাথে এপিআইয়ের বীজ বুদ্ধিমান চালাকি কি? আমি এখনও এটি করব না! বিদ্রোহী!
সামারমন

1
@ivan_bilan matchসৌন্দর্য একটু fasterঅনুসন্ধানের চাইতে যখন একই রেগুলার এক্সপ্রেশন ব্যবহার কিন্তু আপনার উদাহরণ একটি কার্যকারিতা পরীক্ষা অনুযায়ী ভুল বলে মনে হয়: stackoverflow.com/questions/180986/...
baptx

101

search The স্ট্রিংয়ের যে কোনও জায়গায় কিছু খুঁজে বার করুন এবং একটি ম্যাচ অবজেক্ট ফিরিয়ে দিন।

matchThe স্ট্রিংয়ের শুরুতে কিছু সন্ধান করুন এবং একটি ম্যাচ অবজেক্ট ফিরিয়ে দিন।


49

re.search স্ট্রিং জুড়ে প্যাটার্নগুলির জন্য অনুসন্ধান করুন , যদিও প্যাটার্নটি অনুসন্ধানre.match করে না ; যদি এটি না হয় তবে স্ট্রিংয়ের শুরুতে এটির সাথে মিল ছাড়া অন্য কোনও বিকল্প নেই ।


5
কেন শুরুতেই মিলছে, তবে স্ট্রিংয়ের শেষ পর্যন্ত নয় ( fullmatchফাইটন ৩.৪ এ)?
স্মিথ জন্থ

49

মিলটি অনুসন্ধানের চেয়ে অনেক দ্রুত, সুতরাং আপনি regex.search ("শব্দ") না করে আপনি regex.match ((। *?) শব্দ (। *?)) করতে পারেন এবং লক্ষ লক্ষের সাথে কাজ করছেন যদি আপনি প্রচুর পারফরম্যান্স অর্জন করতে পারেন নমুনা।

উপরের গৃহীত উত্তরের নীচে @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 টি পরিমাপ করেছি (1 এম, 2 এম, ..., 10 এম শব্দ) যা আমাকে নিম্নলিখিত প্লট দিয়েছে:

মিল বনাম অনুসন্ধান সন্ধানী গতিবেগ লাইন প্লট

ফলস্বরূপ লাইনগুলি আশ্চর্যরূপে (আসলে যে আশ্চর্যরকম নয়) সরাসরি। এবং searchফাংশনটি (সামান্য) দ্রুত এই নির্দিষ্ট প্যাটার্ন সংমিশ্রণে দেওয়া হয়। এই পরীক্ষার নৈতিকতা: আপনার কোডকে বেশি মাত্রায়িত করা এড়িয়ে চলুন।


11
আসলে বিবৃতিটির পিছনে অনুমানগুলি তদন্তের জন্য +1 যা মূল্যের মূল্য হিসাবে নেওয়া হবে - ধন্যবাদ
রবার্ট ডডিয়র

প্রকৃতপক্ষে @ivan_bilan এর মন্তব্য ভুল দেখাচ্ছে তবে আপনি যদি একই নিয়মিত অভিব্যক্তিটি তুলনা করেন তবে ফাংশনটি matchএখনও searchফাংশনটির চেয়ে দ্রুত faster আপনি তুলনা করে আপনার স্ক্রিপ্টের মধ্যে পরীক্ষা করতে পারবেন 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ফাংশনের মতো দ্রুত হওয়া উচিত ।
baptx

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 অবজেক্টটি (অথবা কোনওটি পাওয়া না গেলে) ফিরে আসবে। 'এবিসি' পেতে, আপনাকে t.group ()
সানড

30

পার্থক্যটি হ'ল পার্ল , গ্রেপ , বা নিয়মিত এক্সপ্রেশন ম্যাচেরre.match() সাথে অভ্যস্ত যে কাউকে বিভ্রান্ত করে। re.search():-)

আরও গভীরভাবে, জন ডি কুক মন্তব্য করেছেন , re.match()"এমন আচরণ করে যেন প্রতিটি প্যাটার্নের ^ চাপ দেওয়া আছে।" অন্য কথায়, re.match('pattern')সমান re.search('^pattern')। সুতরাং এটি একটি প্যাটার্নের বাম দিকটি অ্যাঙ্কর করে। তবে এটি কোনও প্যাটার্নের ডান দিকটিও অ্যাঙ্কর করে না: এটি এখনও একটি সমাপ্তি প্রয়োজন $

স্পষ্টভাবে উপরের দেওয়া, আমার মনে হয় re.match()অবমূল্যায়ন করা উচিত। এটি বজায় রাখা উচিত কারণগুলি জানতে আগ্রহী হব।


4
"এমন আচরণ করে যেন প্রতিটি প্যাটার্নের ^ চাপ দেওয়া থাকে।" আপনি যদি মাল্টলাইন বিকল্পটি ব্যবহার না করেন তবেই সত্য। সঠিক বিবৃতিটি "... আছে
prep

14

পুনরায় ম্যাচ স্ট্রিংয়ের শুরুতে কোনও প্যাটার্নটি মেলানোর চেষ্টা করে । পুনরায় অনুসন্ধান এটি স্ট্রিং জুড়ে প্যাটার্নটি মিলানোর চেষ্টা করে যতক্ষণ না এটি কোনও মিল খুঁজে পায়।


3

অনেক খাটো:

  • search পুরো স্ট্রিং মাধ্যমে স্ক্যান।

  • match স্ট্রিংয়ের শুরুতে স্ক্যান করে।

অনুসরণকারী প্রাক্তন এটি বলেছেন:

>>> a = "123abc"
>>> re.match("[a-z]+",a)
None
>>> re.search("[a-z]+",a)
abc
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.