Skip to content

Commit babe895

Browse files
author
Saeid Darvish
committed
l16: compelete match & fullmatch functions
1 parent 7b5cb6d commit babe895

1 file changed

Lines changed: 131 additions & 8 deletions

File tree

lessons/l16.rst

Lines changed: 131 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@
222222
>>> match.groups()
223223
('Jazz', 'Rock', 'Pop')
224224

225-
>>> match.expand('-->\1---->\2------>\3') # Wrong result!!!
225+
>>> match.expand('-->\1---->\2------>\3') # Warning!!!
226226
'-->\x01---->\x02------>\x03'
227227

228228
>>> match.expand('-->\\1---->\\2------>\\3')
@@ -232,24 +232,34 @@
232232
'-->Jazz---->Rock------>Pop'
233233

234234

235+
::
236+
237+
# \1, \2 and \3 are all valid escape characters
238+
239+
\1 # (U+0001 or 0x01) stands for the ascii start-of-heading character
240+
\2 # (U+0002 or 0x02) stands for the ascii start-of-text character
241+
\3 # (U+0003 or 0x03) stands for the ascii end-of-text character
242+
235243
.. note::
236244
در نمونه کد بالا، خروجی نخستین استفاده از متد ``expand`` متناسب با انتظار نیست، دلیل هم مربوط به وجود کاراکترهایی با ``\`` است (escape characters) که باعث بروز اخلال در تحلیل رشته قالب شده است. بهتر است همیشه در این مواقع از قوانین **raw string** پیروی نماییم: استفاده از ``\\`` به جای ``\`` (همانند ``n\\``) یا قرار دادن یک کاراکتر ``r`` یا ``R`` در ابتدای رشته (همانند ``'r'\n``). در این صورت کاراکترهایی همچون newline یا ``n\`` در رشته، معنای خود را از دست می‌دهند. (یادآوری از درس هفتم)
237245

246+
در واقع مفسر پایتون پیش از قراردادن متن مورد نظر ما در قالب یک شی رشته (string) در حافظه (memory) آن را تحلیل و مقادیر متناسب با کاراکترهای ``\`` را در آن جایگذاری می‌کند که این کار ممکن است در هنگام استفاده ماژول ``re`` از آن شی رشته اخلال ایجاد کند. استفاده از **raw string** باعث می‌شود مفسر پایتون متن مورد نظر را بدون تغییر در حافطه قرار دهد.
247+
238248

239249
.. tip::
240250
بلای Backslash [`اسناد پایتون <https://docs.python.org/3/howto/regex.html#the-backslash-plague>`__]
241251

242-
همیشه در هنگام کار با RegEx (نه فقط در زبان پایتون!) مواظب escape characters یا backslash characters باشید.
252+
همیشه در هنگام کار با RegEx (نه فقط در زبان پایتون!) مواظب escape characters یا همان backslash characters باشید. تا این لحظه برای جلوگیری از پیچیدگی در مثال‌های ارائه شده مبحث RegEx از قرار دادن **raw string** صرف نظر شده بود اما از آنجا که الگوهای RegEx پر از ``\`` است همواره می‌بایست به لزوم استفاده از **raw string** فکر کنیم.
243253

244254
::
245255

246-
>>> match = re.search('(?P<num>\d+)', 'Top 100 songs')
256+
>>> match = re.search(r'(?P<num>\d+)', 'Top 100 songs')
247257
>>> match.group(1)
248258
'100'
249259

250-
>>> match.expand('--- \g<num> ---')
260+
>>> match.expand(r'--- \g<num> ---')
251261
'--- 100 ---'
252-
>>> match.expand('--- \g<1> ---')
262+
>>> match.expand(r'--- \g<1> ---')
253263
'--- 100 ---'
254264

255265

@@ -272,7 +282,7 @@
272282

273283
::
274284

275-
>>> match = re.search("(\d+)\.(\d+)", "24.1632")
285+
>>> match = re.search(r"(\d+)\.(\d+)", "24.1632")
276286

277287
>>> match.start()
278288
0
@@ -295,7 +305,7 @@
295305

296306
این متد یک شی تاپل دوتایی از خروجی دو متد ``start`` و ``end`` را بر می‌گرداند و همانند آنها نیز یک آرگومان اختیاری دارد - نمونه خروجی: ``(m.start(group), m.end(group))``::
297307

298-
>>> match = re.search("(\d+)\.(\d+)", "24.1632")
308+
>>> match = re.search(r"(\d+)\.(\d+)", "24.1632")
299309
>>> match.span()
300310
(0, 7)
301311
>>> match.span(1)
@@ -325,7 +335,7 @@
325335

326336
::
327337

328-
>>> match = re.search("(\d+)\.(\d+)", "24.1632")
338+
>>> match = re.search(r"(\d+)\.(\d+)", "24.1632")
329339

330340
>>> match.re
331341
re.compile('(\\d+)\\.(\\d+)')
@@ -334,7 +344,120 @@
334344
'24.1632'
335345

336346

347+
تابع ``match``
348+
~~~~~~~~~~~~~~~~~~~~~~
349+
350+
351+
``match(pattern, string, flags=0)``
352+
353+
تابع ``match`` از ابتدای string انطباق pattern را انجام می‌دهد، در صورت موفقیت یک شی ``Match`` و در غیر این صورت ``None`` برمی‌گرداند [`اسناد پایتون <https://docs.python.org/3/library/re.html#re.match>`__]::
354+
355+
>>> import re # Python 3.x
356+
357+
>>> match = re.match(r'\d+', '123@USERNAME')
358+
>>> print(match)
359+
<re.Match object; span=(0, 3), match='123'>
360+
361+
>>> match = re.match(r'\d+', 'USERNAME@123')
362+
>>> print(match)
363+
None
364+
365+
366+
>>> match = re.search(r'\d+', '123@USERNAME')
367+
>>> print(match)
368+
<re.Match object; span=(0, 3), match='123'>
369+
370+
>>> match = re.search(r'\d+', 'USERNAME@123')
371+
>>> print(match)
372+
<re.Match object; span=(9, 12), match='123'>
373+
374+
375+
.. tip::
376+
377+
تفاوت دو تابع ``match`` و ``search`` [`اسناد پایتون <https://docs.python.org/3/library/re.html#search-vs-match>`__]:
378+
379+
هنگام استفاده از تابع ``match``، از همان ابتدای متن مورد نظر می‌بایست با الگو تطابق صورت پذیرد (حتی در متن‌های چند سطری) ولی تابع ``search`` انجام انطباق را در هر جایی از متن دنبال می‌کند.
380+
381+
هنگام استفاده از نشانه ``re.MULTILINE`` در تابع ``search``، کاراکتر ``^`` در الگو از معنای **ابتدای متن** به معنای **ابتدای هر سطر** تغییر می‌کند ولی از نظر تابع ``match`` وجود کاراکتر ``^`` در الگو همواره به معنی ابتدای متن می‌باشد (نه هر سطر)::
382+
383+
>>> import re
384+
>>> string = 'Perl\nPython\nRuby' # 3 lines
385+
386+
>>> match = re.search('^Perl', string)
387+
>>> print(match)
388+
<re.Match object; span=(0, 4), match='Perl'>
389+
390+
>>> match = re.search('^Python', string)
391+
>>> print(match)
392+
None
393+
394+
>>> match = re.search('^Python', string, re.MULTILINE)
395+
>>> print(match)
396+
<re.Match object; span=(5, 11), match='Python'>
397+
398+
399+
>>> match = re.match('^Perl', string)
400+
>>> print(match)
401+
<re.Match object; span=(0, 4), match='Perl'>
402+
403+
>>> match = re.match('^Python', string, re.MULTILINE)
404+
>>> print(match)
405+
None
406+
407+
408+
اجازه بدهید یادآوری کنیم که دو نمونه کد زیر عملکردی معادل یکدیگر دارند::
409+
410+
411+
>>> pattern = re.compile('Py...n')
412+
>>> match = pattern.match('Python is great')
413+
414+
::
415+
416+
>>> match = re.match('Py...n', 'Python is great')
417+
418+
419+
تابع ``fullmatch``
420+
~~~~~~~~~~~~~~~~~~~~~~
421+
422+
423+
``fullmatch(pattern, string, flags=0)``
424+
425+
این تابع (``fullmatch``) چنانچه تمام string با pattern انطباق داشته باشد یک شی ``Match`` و در غیر این صورت ``None`` برمی‌گرداند [`اسناد پایتون <https://docs.python.org/3/library/re.html#re.fullmatch>`__] - این تابع از **پایتون نسخه 3.4** به بعد در دسترس است::
426+
427+
>>> import re # Python >= 3.4
428+
429+
>>> match = re.fullmatch(r'\d+', '123@USERNAME')
430+
>>> print(match)
431+
None
432+
433+
>>> match = re.fullmatch(r'\d+', '123')
434+
>>> print(match)
435+
<re.Match object; span=(0, 3), match='123'>
436+
437+
**عملکرد نمونه کدهای زیر برابر هم هستند - به الگو و نام توابع توجه نمایید**::
438+
439+
>>> match = re.search(r'^\d+$', '123')
440+
>>> print(match)
441+
<re.Match object; span=(0, 3), match='123'>
442+
443+
>>> match = re.match(r'\d+$', '123')
444+
>>> print(match)
445+
<re.Match object; span=(0, 3), match='123'>
446+
447+
>>> match = re.fullmatch(r'\d+', '123')
448+
>>> print(match)
449+
<re.Match object; span=(0, 3), match='123'>
450+
451+
452+
همچنین باید یادآوری کنیم که دو نمونه کد زیر عملکردی معادل یکدیگر دارند::
453+
454+
455+
>>> pattern = re.compile('Py...n')
456+
>>> match = pattern.fullmatch('Python')
457+
458+
::
337459

460+
>>> match = re.fullmatch('Py...n', 'Python')
338461

339462

340463

0 commit comments

Comments
 (0)