Python-এ regular expression: ফাঁদসহ ব্যবহারিক গাইড

Regular expression লেখা খুঁজে নতুন রূপ দেয়। group, greedy বনাম lazy, বাংলাদেশি মোবাইল নম্বর যাচাই ও যে backtracking ফাঁদ server জমিয়ে দিতে পারে তা শিখুন।

ম্যাগনিফায়ারের নিচে লেখার একটি লাইনে মিলে যাওয়া অংশ বন্ধনীতে হাইলাইট করা

Regular expression (regex) লেখার একটি pattern বর্ণনা করে, যাতে আপনি তা খুঁজতে, যাচাই করতে বা নতুন রূপ দিতে পারেন। log, সহজ validation ও পরিষ্কারের কাজে চমৎকার, আর যা এটি ভালো পারে না তাতে ভুল ব্যবহার সহজ। নিচের code ও output প্রকাশের আগে Python 3-এ চালানো।

মূল উপাদান

  • \d অঙ্ক, \w অক্ষর, অঙ্ক বা underscore, \s ফাঁকা, . নতুন লাইন ছাড়া যেকোনো অক্ষর।
  • + এক বা একাধিক, * শূন্য বা বেশি, ? ঐচ্ছিক, {4} ঠিক চারটি।
  • [A-Z] একটি সেটের অক্ষর, ^ শুরু, $ শেষ।
  • ( ... ) group, (?P<name> ... ) named group।
  • pattern raw string-এ (r"...") লিখুন, যাতে backslash regex engine-এ পৌঁছায়।

পরীক্ষিত ভ্রমণ

import re

log = "2026-10-29 ERROR payment failed order=1042 user=amina@example.com"
m = re.search(r"(?P<date>\d{4}-\d{2}-\d{2}) (?P<level>[A-Z]+) (?P<msg>.*?) order=(?P<order>\d+)", log)
print(m.groupdict())

print(re.findall(r"[\w.+-]+@[\w-]+\.[\w.]+", "mail amina@example.com or ravi@mail.test today"))

html = "<b>one</b> and <b>two</b>"
print("greedy:", re.findall(r"<b>.*</b>", html), "| lazy:", re.findall(r"<b>.*?</b>", html))

print(re.sub(r"(\d{4})-(\d{2})-(\d{2})", r"\3/\2/\1", "due 2026-11-03"))

phone = re.compile(r"^(?:\+?88)?01[3-9]\d{8}$")
print([bool(phone.match(x)) for x in ["01712345678", "+8801712345678", "8801712345678", "0171234567", "02112345678"]])
{'date': '2026-10-29', 'level': 'ERROR', 'msg': 'payment failed', 'order': '1042'}
['amina@example.com', 'ravi@mail.test']
greedy: ['<b>one</b> and <b>two</b>'] | lazy: ['<b>one</b>', '<b>two</b>']
due 03/11/2026
[True, True, True, False, False]

লক্ষ্য করুন:

  • Named group log লাইনকে নামে পড়া যায় এমন dictionary বানায়।
  • Greedy বনাম lazy। .* যতটা পারে নেয় এবং দুটি bold ট্যাগই গিলেছে, আর .*? প্রথম </b>-এ থামে।
  • re.sub group আবার ব্যবহার করে (\3/\2/\1) তারিখের ক্রম বদলায়।
  • ফোন যাচাই 017..., +88017... ও 88017... নেয় এবং অঙ্ক কম হলে বাদ দেয়। এটি বাংলাদেশের প্রচলিত মোবাইল ফরম্যাটের উদাহরণ, প্রতিটি বৈধ নম্বরের পূর্ণ নিয়ম নয়।

ফাঁদ: catastrophic backtracking

কিছু pattern প্রায়-মেলা input-এ সূচকীয় হারে বেশি সময় নেয়। এভাবে একটি request-ই server জমিয়ে দিতে পারে (ReDoS)।

import re, time

def run(pattern, n):
    s = "a" * n + "b"
    t = time.perf_counter(); re.match(pattern, s); return time.perf_counter() - t

for n in (20, 22, 24):
    print(f"(a+)+$ on {n} a's then b: {run(r'(a+)+$', n):.3f} s | a+$: {run(r'a+$', n):.6f} s")
(a+)+$ on 20 a's then b: 0.031 s | a+$: 0.000057 s
(a+)+$ on 22 a's then b: 0.121 s | a+$: 0.000006 s
(a+)+$ on 24 a's then b: 0.473 s | a+$: 0.000008 s

nested quantifier (a+)+-এ দুটি অক্ষর বাড়ালে প্রায় চার গুণ সময় লেগেছে, অথচ নিরাপদ a+$ তাৎক্ষণিক। দীর্ঘ string-এ এটি মিনিটে গিয়ে ঠেকে।

নিরাপদ থাকবেন যেভাবে

  • (a+)+, (.*)* ও (a|aa)+-এর মতো nested quantifier এড়ান।
  • ব্যবহারকারীর লেখায় মেলানোর আগে input-এর দৈর্ঘ্যের সীমা দিন।
  • যথেষ্ট হলে সহজ টুল পছন্দ করুন: str.startswith, split, in, বা HTML ও JSON-এর জন্য আসল parser।
  • email-এ হালকা যাচাই করুন ও নিশ্চিতকরণ বার্তা পাঠান। regex প্রমাণ করতে পারে না একটি ঠিকানা কাজ করে।
  • একটি pattern বহুবার ব্যবহার হলে re.compile একবার করুন।

সাধারণ ভুল

  • HTML parse করতে regex ব্যবহার। parser ব্যবহার করুন।
  • raw string prefix ভুলে ভুল করে backslash দ্বিগুণ করা।
  • re.search চাওয়ার জায়গায় re.match (match শুধু শুরু দেখে)।
  • anchor ভুলে যাওয়া, ফলে \d{4} দীর্ঘ সংখ্যার ভেতরেও মেলে।
  • কাজ ভাগ করার বদলে একটি বিশাল pattern লেখা।

মূল কথা: named group ব্যবহার করুন, সবচেয়ে ছোট মিল চাইলে lazy quantifier নিন, pattern-এ anchor দিন, আর অবিশ্বস্ত input-এ nested quantifier-সহ pattern কখনও চালাবেন না।


Programming roadmaps সিরিজ, পর্ব ৩ (ভালো Python লেখা): 2 নম্বর (মোট 5)। আগের লেখা: Python virtual environment ও packaging: পরিষ্কার সেটআপ.

আরও পড়ুন

Greedy algorithm: interval scheduling ও greedy কখন ব্যর্থ

Greedy algorithm প্রতি ধাপে এখনকার সেরা মনে হওয়া পছন্দ নেয়। এটি দ্রুত ও কখনও সর্বোত্তম। interval scheduling, greedy ভুল হওয়া একটি coin উদাহরণ ও যাচাইয়ের উপায় দেখুন।

Interview ও DSA•৩ মিনিটে পড়া