ویژگی تصویر

کتابخانه re در پایتون — مرجع کامل و کاربردی

  /  پایتون   /  کتابخانه re در پایتون
بنر تبلیغاتی الف

کتابخانه re در پایتون ابزار اصلی برای کار با الگوهای منظم (Regular Expressions یا Regex) است. این کتابخانه امکان جستجو، استخراج، جایگزینی و تقسیم رشته‌ها بر اساس الگوهای پیچیده را فراهم می‌کند. در این مقاله به مفاهیم پایه، توابع مهم، نکات عملکردی و مثال‌های عملی می‌پردازیم تا بتوانید از re به صورت حرفه‌ای استفاده کنید.

مفاهیم پایه و کاراکترهای متا

  • کاراکترهای متا: . ^ $ * + ? { } [ ] | ( )
  • کوتاه‌شده‌ها: d (اعداد)، w (حروف، اعداد، _)، s (فاصله‌ها)
  • گروه‌ها: ( ) برای گروه‌بندی و گرفتن capture، (?: ) برای گروه غیرقابضی
  • Lookahead / Lookbehind: (?=…), (?!…), (?<=…), (?<!…)
  • Raw string: همیشه الگوها را با r’…’ بنویسید تا بک‌اسلش‌ها به‌درستی تفسیر شوند.

توابع کلیدی و مثال‌های پایه

پرکاربردترین توابع در کتابخانه re عبارت‌اند از: search، match، findall، finditer، sub، split، compile. در ادامه مثال‌هایی کاربردی داریم.

import re

text = "Email: alice@example.com, Phone: +98-912-345-6789"
email = re.search(r'[w.+-]+@[w-]+.[w.-]+', text)
print(email.group(0))  # alice@example.com

در این مثال با re.search اولین تطابق آدرس ایمیل از رشته استخراج می‌شود. r’…’ به معنای raw string است تا بک‌اسلش‌ها تفسیر نشوند.

findall و finditer

phones = re.findall(r'+?d{1,3}[-s]?d{3}[-s]?d{3}[-s]?d{4}', text)
for m in re.finditer(r'+?d{1,3}[-s]?d{3}[-s]?d{3}[-s]?d{4}', text):
    print(m.group(0), m.span())

findall مجموعه‌ای از رشته‌های تطابق‌یافته بازمی‌گرداند؛ finditer یک iterator از Match objectها می‌دهد که برای دستیابی به مکان (span) مفید است.

جایگزینی و تابع callback

def mask_email(m):
    user, domain = m.group(1), m.group(2)
    return user[0] + "***@" + domain

text = "Contact: alice@example.com"
result = re.sub(r'([w.+-]+)@([w-]+.[w.-]+)', mask_email, text)
print(result)  # Contact: a***@example.com

در این نمونه از re.sub با تابع استفاده کرده‌ایم تا منطق پیچیده‌تری برای جایگزینی اعمال شود؛ گروه‌های capture با شماره یا نام قابل دستیابی هستند.

کامپایل الگو و flagها

pattern = re.compile(r'^s*(?Pw+)s*=s*(?P.+?)s*$', re.MULTILINE)
for m in pattern.finditer("name=Johnnage=30n"):
    print(m.group('key'), m.group('value'))

re.compile الگو را می‌سازد و با استفاده از flagها مانند re.IGNORECASE، re.MULTILINE، re.DOTALL و re.VERBOSE می‌توان رفتار را تغییر داد. Named groups با (?P…) تعریف می‌شوند که خوانایی کد را بالا می‌برد.

گریدی در مقابل نان-گریدی (Greedy vs Non-Greedy)

text = "boldstrong"
# Greedy
print(re.findall(r'.*', text))
# Non-greedy
print(re.findall(r'.*?', text))

الگوی greedily همه بین اولین <b> و آخرین </b> را می‌گیرد؛ با ? می‌توان آن را non-greedy کرد تا هر جفت برچسب جداگانه استخراج شود.

مثال‌های کاربردی: اعتبارسنجی، استخراج لاگ و تقسیم متن

  • اعتبارسنجی ایمیل و شماره تلفن
  • استخراج فیلدها از فایل‌های لاگ
  • تکه‌بندی متن (tokenization) در پردازش زبان طبیعی
# ساده‌شده: اعتبارسنجی شماره موبایل ایران
mobile_re = re.compile(r'^(?:+98|0)?9d{9}$')
print(bool(mobile_re.match('09123456789')))  # True
print(bool(mobile_re.match('+989123456789')))  # True

مثال بالا یک الگوی ساده برای شماره موبایل ایرانی است که پیش‌شماره را می‌پذیرد. توجه داشته باشید برای کاربردهای تولیدی ممکن است نیاز به دقیق‌تر کردن الگو باشد.

مقایسه توابع (جدول مرجع)

تابعکاربرد
re.searchپیدا کردن اولین موقعیت که الگو در رشته وجود دارد
re.matchبررسی تطابق از ابتدای رشته
re.findallبازگرداندن همه تطابق‌ها به صورت لیست رشته‌ای
re.finditerبازگرداندن iterator از Match objectها
re.subجایگزینی متن مطابق الگو
re.splitتقسیم رشته بر اساس الگو

نکات عملکردی و جلوگیری از backtracking فاجعه‌آمیز

الگوهای پیچیده با ترکیب‌های تکرارشونده می‌توانند منجر به catastrophic backtracking شوند؛ یعنی زمان اجرای بسیار طولانی برای ورودی‌های خاص. برای جلوگیری:

  • از الگوهای ساده‌تر و مشخص‌تر استفاده کنید.
  • از non-greedy quantifiers و groupهای غیرقابضی (?:…) استفاده کنید.
  • در مواقع حساس از ماژول third-party مانند “regex” استفاده کنید که گزینه‌هایی برای possessive quantifiers و atomic grouping دارد.
  • الگوها را با re.compile پیش‌کامپایل کنید تا هزینه پارس کاهش یابد.
# نمونه‌ای از الگوی پرخطر و نسخه بهینه‌تر
import re
s = "a"*30 + "!"

# پرخطر (ممکن است زمان‌بر باشد)
bad = re.match(r'(a+)+!', s)

# بهتر: از non-capturing و محدودیت استفاده کنیم
good = re.match(r'(?:a{1,30})!', s)

در مثال بالا تجمیع گروه‌های تودرتو با + می‌تواند باعث backtracking شود؛ با محدود کردن تعداد تکرار یا استفاده از غیرقابضی می‌توان آن را بهبود داد.

نکات حرفه‌ای و بهترین روش‌ها

  • همیشه از r’…’ برای الگوها استفاده کنید تا از خطاهای بک‌اسلش جلوگیری شود.
  • برای خوانایی از re.VERBOSE استفاده کنید و الگو را به صورت چندخطی توضیح دهید.
  • در صورت نیاز به قابلیت‌های پیشرفته‌تر (مثل possessive quantifiers یا atomic groups)، از کتابخانه “regex” بهره ببرید.
  • برای استخراج داده‌ها از match.groupdict و named groups استفاده کنید تا کد خواناتر شود.
  • الگوها را تست کنید: از ابزارهای آنلاین یا ماژول unit test برای پوشش حالات مرزی بهره ببرید.

جمع‌بندی

کتابخانه re در پایتون یک ابزار قدرتمند و همه‌کاره برای کار با الگوهای متنی است. با درک مفاهیم پایه مثل گروه‌ها، quantifierها و flagها و با رعایت نکات عملکردی، می‌توانید وظایف معمول پردازش متن، اعتبارسنجی و استخراج داده را به‌صورت مؤثر اجرا کنید. اگر به قابلیت‌های بیشتر نیاز دارید، ماژول‌های جایگزین نیز موجود هستند اما برای اکثر کاربردهای روزمره re کافی و کارآمد است.

آیا این مطلب برای شما مفید بود ؟

خیر
بله
موضوعات شما در انجمن: