রেগুলার এক্সপ্রেশন (Regular Expression)

রেগুলার এক্সপ্রেশন (সংক্ষিপ্তরূপ: regex বা regexp) হচ্ছে ক্যারেক্টার আর সিম্বলের সিকুয়েন্স যেটার সাহায্যে আপনি নির্দিষ্ট প্যাটার্ন এর টেক্সট বা স্ট্রিং সার্চ করতে পারবেন এবং সেটার উপর ভিত্তি করে অ্যাকশন নিতে পারবেন।

একটা উদারহণ দেওয়া যাক

ধরা যাক আমাদের বিশাল একটা টেক্সট ফাইল দেওয়া হল। যেখানে অনেক গুলো লেখার মাঝে মাঝে ইমেইল ও রয়েছে। আমাদের শুধু ইমেইল গুলো বের করতে হবে। ধরা যাক এক লক্ষ ইমেইল রয়েছে ঐ বিশাল টেক্সট ফাইলের মধ্যে। এখন কাউকে যদি ইমেইল গুলো খুজে বের করতে বলে, তাহলে অনেক সময় লাগবে। আবার অনেক গুলো ইমেইল সে হয়তো চোখের ভুলের কারণে মিস করে যাবে। আমাদের দরকার অটোমেটিক কিছু। আর এ কাজ টাই করে রেগুলার এক্সপ্রেশনে। আমাদের আগে একটা সার্চ প্যাটার্ণ তৈরি করতে হবে। ইমেইল এড্রেসে কি কি থাকে সে গুলো এনালাইসিস করে। যেমন একটা ডকুমেন্ট থেকে ইমেইল গুলো বের করার সার্চ প্যাটার্ণ হতে পারে নিচের মতঃ

 
 
 
\b[A-Z0-9._%+-]+@[A-Z0-9.]+\.[A-Z]{2,}\b
 

উপরের প্যাটার্ণ দেখে ভয় পাবার কিছু নেই একবার বুঝলেই সহজ হয়ে যাবে। উপরের এটা একটা উদারহণ, আমরা আরো ছোট খাটো উদাহরণ দিয়ে দেখব। তারপর কিভাবে কমপ্লেক্স সার্চ প্যাটার্ন তৈরি করতে পারি, তা দেখব।

আমরা পাইথনে রেগুলার এক্সপ্রেশন নিয়ে কাজ করার জন্য পাইথন আমাদের একটি রেগুলার এক্সপ্রেশন মডিউল দিয়ে রেখেছে। যা ব্যবহার করে খুব সহজে রেগুলার এক্সপ্রেশন সব অপেরেশন করা যায়। পাইথনে ঐ রেগুলার এক্সপ্রেশন মডিউল হচ্ছে re এবং ইম্পোর্ট করার জন্য নিচের এই লাইন টি আমাদের কোড এ যুক্ত করতে হবে।

 
 
 
import re
 

রেগুলার এক্সপ্রেশনে কয়েক ধরনের ক্যারেক্টার সেট আছে। এগুলোর ব্যবহারের উপর ভিত্তি করে

  • Metacharacter
  • Brackets
  • Group

নামে বিভক্ত করা যায়। নিশ্চয়ই এখন মাথা ঘুরতেছে এগুলো আবার কি। সমস্যা নেই, সবগুলো নিয়েই নিচে লিখে দেয়া হলোঃ

মেটাক্যারেক্টার (Metacharacter)
মেটাক্যারেক্টার হচ্ছে স্পেশাল কিছু ক্যারেক্টার, যেগুলোর স্পেশাল মিনিং আছে। একই টাইপের কোনো ক্যারেক্টার ম্যাচ করানোর জন্যেই সাধারণত এই মেটাক্যারেক্টারগুলো ব্যবহার করা হয়।

. (dot)
এই মেটা ক্যারেক্টারের মাধ্যমে যেকোনো ক্যারেক্টার ম্যাচ করার নির্দেশ দেয়া হয় (শুধু নিউ লাইন ক্যারেক্টার বাদে)। উদাহরণ,

 
 
 
import re
 
pattern = r“ab.d”
 
if re.match(pattern, “abcd”):
print(“abcd match 1”)
else:
print(“abcd match 1”)
if re.match(pattern, “abed”):
print(“abed match 2”)
else:
print(“abed match 2”)
 
if re.match(pattern, “xyzw”):
print(“xyzw match 3”)
else:
print(“xyzw not match 3”)
 
 
#output
#abcd match 1
#abed match 2
#abcd not match 3
 

উপরে আমরা একটি রেগুলার এক্সপ্রেশন ডিফাইন করেছি r”ab.d” এর মাধ্যমে। এখানে . দিয়ে ওই অবস্থানে যেকোনো ক্যারেক্টার এর সাথে ম্যাচ দেখতে বলা হয়েছে। আর তাই যখন abcd বা abed এর সাথে ম্যাচ করা হয়েছে তখন রেজাল্ট সত্য এসেছে এবং একটি প্রিন্ট স্টেটমেন্ট এক্সিকিউট হয়েছে। xyzw এর ক্ষেত্রে তা হয় নি।

^ এবং $
আরও দুটি বহুল ব্যবহৃত মেটা ক্যারেক্টার হচ্ছে ^ এবং $. এ দুটোর মাধ্যমে যথাক্রমে কোন একটি স্ট্রিং এর শুরু এবং শেষ চেক করে দেখা হয়। যেমন,

 
 
 
import re
 
pattern = r“^ab.d$”
 
if re.match(pattern, “abcd”):
print(“abcd match 1”)
else:
print(“abcd match 1”)
if re.match(pattern, “abed”):
print(“abed match 2”)
else:
print(“abed match 2”)
 
if re.match(pattern, “xyzw”):
print(“xyzw match 3”)
else:
print(“xyzw not match 3”)
 
 
# Output
#abcd match 1
#abed match 2
#abcd not match 3
 

এই ছাড়া আরো অনেক গুলো মেটাক্যারেক্টার আছে তা দেখা যাক —

  • \d — 0 থেকে শুরু করে 9 পর্যন্ত যেকোন ডিজিট।
  • \w —(a-z,A-Z,0-9) এই ক্যারেক্টারগুলো দিয়ে গঠিত যেকোন শব্দ
  • \W —\w এর ঠিক উল্টা । (a-z,A-Z,0-9) এই ক্যারেক্টারগুলো ছাড়া গঠিত যেকোন শব্দ।
  • \s— যেকোন whitespace ক্যারেক্টার।
  • \S — \s এর ঠিক উল্টা
  • \b — যেকোন ওয়ার্ড এর বাউন্ডারি বোঝাতে

ব্র্যাকেটস (Brackets)

ব্র্যাকেটস এর ভিতরে কিছু ক্যারেক্টার থাকে যেগুলো বিভিন্ন রেঞ্জের ক্যারেক্টার ম্যাচ করতে ব্যবহার করা হয়ঃ

[abc] — এটা দ্বারা বুঝানো হয় যে আমরা a অথবা b অথবা c এর মধ্যে যেকোনো একটা ক্যারেক্টার ম্যাচ করাতে চাচ্ছি।

 
 
 
import re
 
 
pattern = r“[abc]”
 
if re.search(pattern, “abcd”):
print(“The word ‘abcd’ got at least one pattern word!”)
else:
print(“No pattern word found!”)
 
if re.search(pattern, “xyzw”):
print(“The word ‘xyzw’ got at least one pattern word!”)
else:
print(“No pattern word found!”)
 
 
 
# Output
 
#The word ‘abcd’ got at least one pattern word!
#No pattern word found!
#এই ছাড়া আরো অনেক গুলো ব্র্যাকেটস আছে তা দেখা যাক —
 

[a-z] — a থেকে z পর্যন্ত যেকোনো ক্যারেক্টারের সাথে ম্যাচ করবে।
[a-z] — a, -, বা z এর সাথে ম্যাচ করবে। কারণ – এর আগে \ থাকায় রেঞ্জ কাজ করে না।
[a-] — a বা – ম্যাচ করবে, কারণ রেঞ্জ ম্যাচ করাতে হলে – এর উভয়পাশে কোনো ক্যারেক্টারের উপস্থিতি থাকতে হবে।
[-a] — উপরের হিসাবে, a বা – ম্যাচ করে।
[a-z0-9] — a থেকে z এবং 0 থেকে 9 পর্যন্ত ক্যারেক্টার ম্যাচ করে। বিশেষ ক্যারেক্টারগুলি একটি সেটের অভ্যন্তরে আক্ষরিক হয়ে ওঠে, তাই এটি (, +, এবং *) ম্যাচ করে।
[^ab5] — ^ যোগ করে সেটের যেকোনো ক্যারেক্টার বাদ দেওয়া হয়। এখানে এটি a, b, বা 5 নয় এমন ক্যারেক্টারের সাথে ম্যাচ করে।

  • একটা ফাংশন লিখতে হবে যা দিয়ে আমরা চেক করতে পারবো, কোনো মোবাইল নাম্বার বাংলাদেশ জন্য সঠিক মোবাইল নাম্বার কিনা।

    বাংলাদেশের ফোনের সঠিক ফরম্যাট হচ্ছে: +8801(3/4/5/6/7/8/9)-যেকোন ৮ সংখ্যার নাম্বার
    Args: text (str): random string
    Returns: phone (bool): a valid phone number in the required format

     
     
     
    import re
    def find_valid_phone(phone_number: str)> bool:
    phone_regex = r‘^(?:\+88|88)?(01[3-9]\d{8})$’
    phone_number_check = re.match(phone_regex, phone_number)
     
    if phone_number_check:
    return True
    return False
     
    def main():
    phone_number = input(‘Enter phone number: ‘)
    if find_valid_phone(phone_number):
    print(“phone number is valid”)
    else:
    print(“Invalid phone number”)
     
    if __name__ == ‘__main__’:
    main()
  • অনুশীলনঃ
    • ডিরেক্টরিতে নাই এমন একটি টেক্সট ফাইলের নাম দিয়ে , ফাইলটি ওপেন করার কোড লিখুন
    • Value Error generate করে এমন একটি কোড লিখুন
    • 10 টি আইটেমযুক্ত একটি লিস্টের ১০ নম্বর ইনডেক্স এর ভ্যালু কি হবে ?
    • Index Error generate করে এমন একটি কোড লিখুন
    • Type Error generate করে এমন একটি কোড লিখুন
  • ভ্যরিয়েবলের ডিক্লিয়ার ক্ষেত্রে প্রথম ক্যারেক্টার কি কি ধরনের হয়ে থাকে ?
  • নিচের কোড টা দেখো –
     
     
     
    i_am_string = “hello_world”
    i_am_string = 14
    i_am_string = True
     

    উপরের তিনটি ভ্যরিয়েবলের নাম একই কিন্তু তাদের data type change করার পরেও কোড কোন ভুলে দেখাচ্ছে এবং খুব সুন্দর ভাবে রান হচ্ছে কেনো ?

  • নিচের কোড টা দেখো –
     
     
     
    x = 5 + 3 * 8
     

    উপরের x ভ্যরিয়েবলের রেজাল্ট কি হবে এবং এই রেজাল্ট হবার কারণ কি ?

  • আমাদের কে দুই টি integer data type value দিলে এবং তাদের মধ্যে ভাগ করতে বলল । অই ভাগ ফল সাধারণত কি ধরনের data type হয় ?
  • একটি বুলিয়ান ভ্যরিয়েবলের ডিক্লিয়ার করে তার ভ্যালু আমরা True assign করলাম । এখন যদি আমরা তার সাথে 7 দিয়ে গুন করে তাহলে আমাদের টার্মিনাল এ আউটপুট হিসাবে কি পাবো ?
  •