تا کنون با مفهوم یک RegEx و بخشهای سازنده آن آشنا شدید؛ در قالب تمرینهای گذشته نیز آموختید چگونه مواردی مثل آدرس ایمیل یا IP را با این تکنیک از داخل یک متن آزمایشی به کمک یک سامانه آنلاین (regex101.com) پیدا کنید. اما هدف اصلی ما این است که RegEx ها را داخل برنامههای پایتونی خودمان پیادهسازی کنید. برای این کار به ماژول پایتونی re نیازمندید که به صورت استاندارد با پایتون نصب میشود.
در این قسمت از دوره آموزشهای فنی و کاربردی کامپیوتر با پایتون، ضمن معرفی ماژول re و نحوه وارد کردن آن به برنامه، به معرفی مهمترین توابع این ماژول میپردازید؛ توابعی مثل ()findall برای اعمال جست و جوی روی کل متن مبتنی بر الگوی RegEx، تابع ()sub برای جایگزینی کلمات و موارد دیگر.
کتابخانه re در پایتون
در جلسات قبلی یاد گرفتیم که چگونه از Regex استفاده کنیم و الگوهای آن را بسازیم و در سایت Regex101 تست کنیم. اما هدف ما این است که از این قابلیت در برنامههای پایتونی خود استفاده کنیم.
در این جلسه و جلسهی بعدی میخواهیم توضیح دهیم که چگونه این پترنهایی که نوشتیم و تست کردیم را در پایتون پیادهسازی کنیم و روی سینگالهایی که داریم، آنها را تست کنیم و برنامههایی که میخواهیم را توسعه دهیم.
ما برای اینکه بتوانیم جستوجوها و تطابقهای خود را در پایتون انجام دهیم، نیاز به یک کتابخانهی داخلی به نام re داریم. میتوانیم با دستور
import re این کتابخانه را وارد برنامه کنیم و از آن و متدهایی که درون آن وجود دارد استفاده کنیم تا بتوانیم پترنهای Regex خود را پیادهسازی کنیم.
متدهای مختلفی در این کتابخانه وجود دارد ک در این قسمت با 4 تا از معروف ترینهای آنها اشنا خواهیم شد.
متد ()findall
اولین متدی که در کتابخانه re پایتون داریم، متد ()findall است. با استفاده از این متد میتوانیم همه تطابقهایی که در متن خود داریم را دریافت کنیم. جستجو انجام میدهیم و نتیجه را در قالب یک لیست دریافت میکنیم که هر آیتم آن یکی از این تطابقها است. سینتکس به این صورت است که وقتی ما ماژول re را ایمپورت کردیم، مینویسیم:
re.findall(pattern, string, flags=0)در اینجا ابتدا پترن Regex خود را میدهیم و سپس string که میخواهیم روی آن جستجو انجام دهیم را وارد میکنیم و در نهایت flag را مشخص میکنیم.
در پایتون، pattern را به صورت یک string معمولی میدهیم یا به صورت raw string (راستچین) میدهیم. بر اساس چیزی که pattern ما از آن ساخته شده است، اگر در pattern خود از Backslash (\) و موارد مشابه استفاده کردهایم و pattern ساده نیست، حتماً باید از raw string استفاده کنیم.
همچنین پترنهای Regex که ما میسازیم، در پایتون نمیتوانیم در انتهای پترن، فلگ یا modifier را مستقیماً بنویسیم. اگر فلگ یا modifier دارید، باید در قالب پارامتر flags آن را برگردانید. در اینجا خود اصل پترن را مینویسیم و فلگ را در پارامتر آخر هر کدام از این متدها وارد میکنیم که به صورت پیشفرض هیچ فلگی ندارد.
متد ()Search
دومین متد که در کتابخانه re پایتون داریم، متد ()Search است. متد ()Search، متدی شبیه به متد ()Match است. این متد، عمل جستجو را روی رشته String مورد نظر انجام میدهد و اولین تطابق را در قالب یک شیء از نوع MatchObject برمیگرداند. این شیء متعلق به کتابخانه re است.
نکته مهم این است که اگر هیچ تطابقی پیدا نشد، به جای شیء MatchObject، مقدار None برگردانده میشود.
متد ()Sub
متد بعدی که در کتابخانه re پایتون داریم متد ()Sub است. متد ()Sub معادل متد String.replace در جاوااسکریپت است. این متد بر اساس یک الگو روی رشته جستجو انجام میدهد و تطابقهای پیدا شده را با رشتهای که ما مشخص کردهایم، جایگزین میکند.
پارامتر Count
با استفاده از پارامتر count میتوانیم مشخص کنیم که چند تطابق اول جایگزین شوند:
- اگر مقداری به این پارامتر ندهیم (پیشفرض: 0)،همه تطابقها جایگزین میشوند.
- اگر عدد 2 را وارد کنیم، فقط 2 تطابق اول جایگزین میشوند.
متد ()Split
متد آخر که در کتابخانه re پایتون با آن آشنا میشوید متد ()Split است. متد ()Split یک لیست برمیگرداند. این متد روی متن بر اساس Pattern عمل میکند و هر جا که تطابق Match اتفاق بیفتد، همانجا را برش میزند.
پارامتر Max
این متد پارامتری به نام max دارد که مقدار پیشفرض آن 0 است:
- اگر مقدار 0 را داشته باشد (یا هیچ مقداری ندهیم)، روی هر تطابق برش زده میشود.
- اگر عددی مشخص به آن بدهیم، تعداد برشها را مشخص میکند.
مثلاً اگر بگوییم یک برش بزن، این متد صرفاً روی اولین تطابق برش میزند و بقیه را کار ندارد.
نکته مهم این است که آیتمهای لیست خروجی، در واقع تکههای متن تا قبل از هر تطابق هستند. یعنی این برشها بین هر کدام از Match های ما قرار میگیرند.

MatchObject در کتابخانه re پایتون
این MatchObject در کتابخانه re پایتون خیلی پرکاربرد است. درواقع یک شیء شامل اطلاعات و نتایج جستجوی ماست.
وقتی از متد ()Search استفاده میکنیم و جستجو موفقیتآمیز باشد، این MatchObject برگشته میشود که یک سری اطلاعات درباره آن جستجو را در خود دارد. این اطلاعات داخل MatchObject ذخیره شدهاند و برای اینکه بفهمیم آن اطلاعات چیست، به یک سری متد و ویژگی نیاز داریم که مربوط به این MatchObject است.
در جدول زیر با ۴ تا از متدها و ویژگیهای معروف آن آشنا میشوید. متدهای پرکاربرد دیگری هم دارد اما از موضوع بحث ما خارج است.

متد ()span در MatchObject
این متد روی خروجی سرچ، یعنی همان MatchObject پیاده میشود و به ما یک تاپل دوتایی برمیگرداند:
- عضو اول (ایندکس شروع): ایندکس شروع مچ را نشان میدهد. مثلاً میگوید در ایندکس ۳ این مچ پیدا شده.
- عضو دوم (ایندکس پایان): ایندکس پایان مچ را نشان میدهد.
این ایندکس پایان، اولین ایندکسی است که در مچ وجود ندارد.
اگر مچ ما از ایندکس ۲ تا ۴ باشد، تاپل (2, 5) برگردانده میشود. یعنی ایندکس ۵ اولین ایندکسی است که در مچ وجود ندارد.
string در MatchObject
ویژگی دیگری که داریم، ویژگی string است. اگر بنویسیم match.strin، به ما آن رشتهای که روی آن جستجو انجام دادیم را برمیگرداند.
دقیقاً همان رشتهای که در متد سرچ (search) به آن دادیم، با استفاده از match.string قابل دسترسی است.
متد ()group در MatchObject
این متد، تکه از متن که در آن تطابق اتفاق افتاده را برمیگرداند. میتوانیم در پرانتز این متد، عددی به عنوان ایندکس بدهیم (مثلاً ۰، ۱، ۲). مقدار پیشفرض آن 0 است.
اگر در رجکسی که مینویسید، Capturing Group داشته باشید، میتوانید در اولین تطابقی که پیدا میکنید، به صورت جداگانه به آنها دسترسی داشته باشید.
اگر دو تا Capturing Group داخل رجکس داشته باشید:
- اگر بنویسید group(0): یا هیچی ندهید: کل آن مچ را نشان میدهد.
- اگر بنویسید group(1): اولین Capturing Group را نشان میدهد.
- اگر بنویسید group(2): دومین Capturing Group را نشان میدهد.
اگر Capturing Group نداشته باشید، هر عددی غیر از 0 بدهید، ارور برمیگرداند.
کاربرد MatchObject
کاربرد اصلی MatchObject برای ما در شرطها است. مثلاً اگر بنویسیم:
if string.search(pattern)- مچ ابجکت برگشته → جستجو موفق بوده
- پترن در متن وجود دارد
- کار مد نظر را انجام میدهیم
else:
- نان برگشته → پترن در متن وجود ندارد
- کار دیگری انجام میدهیم
اگر مچ ابجکت برگردانده شود، یعنی جستجو موفق بوده و پترن در متن وجود دارد. اگر None برگردد، شرط if ما False میشود و متوجه میشویم که آن الگو در متن ما نیست.
Flagها در کتابخانه re پایتون
گفتیم که در ریجکس، فلگ را مستقیماً بعد از اسلش میگذاریم. مثلاً اگر بخواهیم مشخص کنیم که بزرگی و کوچکی حروف برای ما مهم نیست Case Insensitiv، از i استفاده میکردیم.
حالا در پایتون، میتوانیم از دستور re.I استفاده کنیم. این یک فلگ مشخص است که معادل همان مودیفایر i است و آن را به پارامتر flags میدهیم.
فلگ Multiline
برای مالتیلاین از فلگ re.M استفاده میکنیم.
متد ()findall
مودیفایر دیگری به نام (Global Search :g) داشتیم که در پایتون مستقیماً استفاده نمیشود. اگر بخواهیم در پایتون Global Search انجام بدهیم، به جای آن از متد ()findall استفاده میکنیم. این متد به تنهایی معادل مودیفایر g است و همه تطابقها را برای ما پیدا میکند. در غیر این صورت، اگر مثلاً از search یا match استفاده کنیم، به صورت خودکار فقط اولین تطابق برگردانده میشود.
درواقع در پایتون، استفاده از مودیفایر g را نداریم و فقط فلگهای I ، M هستند که به صورت فلگ به متدها داده میشوند.
اگر بخواهیم از چندین فلگ استفاده کنیم مثلاً هم I داشته باشیم و هم M در پارامتر flags میآییم از اپراتور OR استفاده میکنیم و آن را بین این دو قرار میدهیم.
flags=re.I | re.M
در قسمت بعد با ما همراه باشید.
