রেগুলার এক্সপ্রেশনঃ উপকারিতা ও ব্যবহারিক প্রয়োগ (Importance and practical use of Regular Expression)

রেগুলার এক্সপ্রেশনঃ
নাম থেকেই বোঝা যাচ্ছে যে, রেগুলার এক্সপ্রেশন (রেজেক্স বা RegEx) আসলে কতগুলো সুনির্দিষ্ট ক্যারেকটারের (Char) সমষ্টি। এই একগুচ্ছ ক্যারেকটারের সমষ্টি একত্রে কোন নির্দিষ্ট প্যাটার্ন প্রকাশ করে যা দিয়ে কোন বিশাল প্যারাগ্রাফ থেকে কোন নির্দিষ্ট প্যাটার্নের অংশ খুঁজে বের করতে পারে। একটি সহজ উদাহরন দেখে নেওয়া যাক। যেমন ধরি, একটি ৫০০ শব্দের প্যারাগ্রাফ থেকে এমন সব শব্দ খুঁজে বের করতে হবে যেগুলোর প্রথম অক্ষর ‘N’, শেষের অক্ষর ‘L’ এবং মাঝে কমপক্ষে একটি ‘H’ থাকবে। যদি ট্র্যাডিশনাল প্রোগ্রামিং দিয়ে এ কাজটি করতে চাই তাহলে কি কি করতে হবে তা নিচে লেখা হলঃ

ধাপ ১ঃ প্যারাগ্রাফ এর প্রথম ক্যারেকটার থেকে শুরু করে একটা একটা করে সামনে আগাতে হবে।
ধাপ ২ঃ কোন শব্দের প্রথম অক্ষর যদি ‘N’ হয় তাহলে এই ইনডেক্সে একটি পয়েন্টার রাখতে হবে। এরপর এই ইনডেক্স থেকে আবার সামনে আগাতে হবে। যদি শব্দটির শেষ অক্ষরে পৌছানোর আগে ‘H’ পাওয়া যায় এবং শেষ অক্ষরটি যদি ‘L’ হয় তাহলে এটা একটি কাঙ্খিত শব্দ। এই শব্দটি কে একটি স্ট্রিং টাইপ অ্যারে তে স্টোর করে রাখি।
ধাপ ৩ঃ যদি এমন হয় যে আমরা শব্দটির শেষ অক্ষরে পৌছে গেছি কিন্তু উপরের দেওয়া প্যাটার্ন ম্যাচ করেনি তাহলে আবার ‘N’ দিয়ে শুরু হওয়া নতুন শব্দ না পাওয়া পর্যন্ত সামনে আগাতে হবে। যদি কোন শব্দের প্রথম অক্ষর ‘N’ হয় তাহলে ধাপ ২ এ ফিরতে হবে।
ধাপ ৪ঃ প্যারাগ্রাফটির শেষ অক্ষর ভিজিট হয়ে গেলে প্রোগ্রামটি বন্ধ হয়ে যাবে।

অবশেষে একটি স্ট্রিং টাইপ অ্যারেতে ওই নির্দিষ্ট প্যাটার্নের সকল শব্দ জমা হবে। উপরে অ্যালগোরিদমটির সংক্ষেপ বর্ননা দেওয়া হল। কিন্তু এই অ্যালগরিদমটির ইমপ্লিমেন্টেশন টা করতে গেলে যাযা লাগবে তা নিচে দেওয়া হলঃ
১। কমপক্ষে ৩ টি ভ্যারিয়েবল যা ফ্ল্যাগ হিসেবে ব্যবহার করা হবে বিভিন্ন ইনডেক্স স্টোর করে রাখার জন্য।
২। একটি For লুপ।
৩। অসংখ্য if-else ব্রাঞ্চিং।
৩। একটি ক্যারেকটার টাইপ স্ট্রিং যেটাতে খুজে পাওয়া কাঙ্খিত সকল শব্দ থাকবে।

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

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

রেজেক্সওয়ান ডট কম থেকে মাত্র এক থেকে দুই ঘন্টা দেখলেই রেগুলার এক্সপ্রেশন সহজে শেখা যাবে। ছোট ছোট সাইজের লেসন এর সাথেই রয়েছে সরাসরি প্র্যাকটিস করার সুযোগ।

রেজেক্সওয়ানিজরোওয়ান ডট কম একটি অনলাইন টুল যা ব্যবহার করে খুব সহজেই কাঙ্খিত রেগুলার এক্সপ্রেশনটি জেনারেট করা যায়।

উদাহরন ও ব্যবহারিক প্রয়োগঃ
যাদের জুমলা ও ভার্চুমার্ট কমপোনেন্ট সম্পর্কে ধারনা আছে তারা নিশ্চয়ই জানি যে, ভার্চুমার্টে যখন কোন প্রোডাক্ট আপলোড হয় তখন ওই প্রোডাক্টের ইমেজ আপলোড করে এবং রিসাইজ করে একই ইমেজের একটি রিসাইজইড ভারসন তৈরী করে। ডাটাবেজের XX_virtuemart_media নামক টেবিলে file_url এবং file_url_thumb নামক কলামে যথাক্রমে মুল ইমেজ ও রিসাইজড ইমেজের পাথ স্টোর করে রাখে। ২০১২ সালের দিকে আমি জুমলার একটি মডিউল বানিয়েছিলাম যেটা একটা নির্দিষ্ট ক্যাটেগরী থেকে কিছু নির্দিষ্ট বৈশিষ্ট্যের সকল প্রোডাক্টের লিস্ট ডিসপ্লে করে। মডিউল টির নাম mod_votecounter যেটি বর্তমানে মডিউলটি এখানে সাইটে রানিং আছে। লিস্ট এ ডানপাশে যে ইমেজ গুলো দেখছেন সেগুলো রিসাইজড ভার্সন ইমেজ। ইমেজের নাম ও পাথ ডাটাবেজের XX_virtuemart_media টেবিলের file_url_thumb কলাম থেকে img ট্যাগ এর মাধ্যমে দেখানো হয়েছে। কিছুদিন আগে সাইটটির মালিক বা আমার ক্লায়েন্ট জুমলা ও ভার্চুমার্ট এর ভার্সন আপগ্রেড করে। এর পর থেকে ওই লিস্টটিতে ডানদিকে আইটেমের ইমেজ দেখাচ্ছিল না। অ্যানালাইসিস করে যা জানলাম, তার সারমর্ম হল এরকম, প্রোডাক্ট ইমেজ আপলোড করার সময় ভার্চুমার্ট কম্পোনেন্ট টি ওই একি ইমেজের রিসাইজ্ড ইমেজ তৈরী করে একই পাথে resized নামক ফোল্ডার এ নির্দিষ্ট নেমিং কনভেনশন ফলো করে রাখে। এই কারনে ভার্চুমার্ট এর লেটেস্ট ভার্সন গুলোতে file_url_thumb টি ফাঁকা থাকে। যেহেতু file_url কলাম থেকেই ওই ইমেজের এবং সেটার রিসাইজড ভার্সনের পাথ পাওয়া সম্ভব তাই ভার্চুমার্ট এখন আর file_url_thumb এ কোন পাথ রাখে না। যদি রিসাইজড ইমেজ টি কোন কারনে ওভাররাইট করা হয় শুধুমাত্র সেক্ষেত্রে file_url_thumb এ ওভাররাইট করা ইমেজের পাথ স্টোর করে রাখে।

সমস্যাঃ
তাহলে লেটেস্ট ভার্সনে file_url_thumb ফাঁকা। আমাকে file_url থেকেই রিসাইজড ইমেজের পাথ জেনারেট করতে হবে। নিচে মুল ইমেজের পাথ ও রিসাইজড ইমেজের পাথ কেমন হবে তার একটি উদাহরন দেওয়া হলঃ

মুল ইমেজ ঃ /images/stories/virtuemart/product/product_photo.jpg
রিসাইজড ইমেজঃ /images/stories/virtuemart/product/resized/product_photo_200x200.jpg

রিসাইজড ইমেজের বোল্ড করা অংশটুকু দেখেই পার্থক্য বোঝা যাচ্ছে। অর্থাৎ আমাকে এখন এমন একটি রেগুলার এক্সপ্রেশন বানাতে হবে যেটা দিয়ে মুল ইমেজ পাথকে ৩ টা ভাগে ভাগ করা যায়। ভাগ গুলো নিম্নরুপঃ
প্রথম অংশ ঃ /images/stories/virtuemart/product/
দ্বিতীয় অংশঃ product_photo
তৃতীয় অংশঃ .jpg
রেজেক্স ইন্জিন কে যদি এই রেগুলার এক্সপ্রেশন ও মুল ইমেজ পাথ টা দেই তাহলে ইন্জিনটি আমাদের কে উপরের মত করে তিনটা আলাদা স্ট্রিং রিটার্ন করবে। এরপর আমরা নিচের মত করে রিসাইজড ইমেজ পাথ জেনারেট করব।
[string1]resized/[string2]_200*200[string3]

তাহলে এখন আমরা এমন একটি মেথড লিখব যা ইনপুট হিসেবে মুল ইমেজের পাথ নিবে এবং রিসাইজড ইমেজের পাথ রিটার্ন করবে।

/**
* @param $media String file_url of product image of virtuemart
* @return $thumb_url string automatically generated thumb url
*/
function generateThumbUrl($media = false){
$thumb_url = preg_replace("/(((w+)/)+)(.+)(.jpg)/i", "$1resized/$4_200x200$5", $media);
return $thumb_url;
}

এই কোডটিতে “(((w+)/)+)(.+)(.jpg)” করা অংশটুকুই একটি রেগুলার এক্সপ্রেশন যে একটা ইমেজ পাথ কে পুর্বের নিয়ম অনুযায়ী তিনটি গ্রুপে ভাগ করবে। preg_replace একটি PHP মেথড যা তিনটি প্যারামিটার ইনপুট হিসেবে নেয়। প্রথমটি হবে রেগুলার এক্সপ্রেশন, দ্বিতীয়টি নতুন স্ট্রিং টির প্যাটার্ন এবং তৃতীয়টিতে মুল স্ট্রিং যেটা থেকে নতুন স্ট্রিং জেনারেট করতে হবে। উপরের কোডটিতে preg_replace মেথডটি $media এর উপর রেগুলার এক্সপ্রেশন (((w+)/)+)(.+)(.jpg) এক্সিকিউট করে অনেকগুলো নেস্টেড ভাগে ভাগ করে যেখানে $1 এ থাকে মুল ইমেজের প্রথম অংশ, $4 এ থাকে দ্বিতীয় অংশ এবং $5 এ থাকবে শেষ অংশ। তাহলে আমাদের নতুন স্ট্রিংটির প্যাটার্ন হবে $1resized/$4_200x200$5

regex101.com এর টুলটি ব্যবহার করে সরাসরি নির্দিষ্ট প্যাটার্নের জন্য রেগুলার এক্সপ্রেশন জেনারেট করা যায়।

এই পোস্টটিতে শুধুমাত্র রেগুলার এক্সপ্রেশনের সম্পর্কে ধারনা দেওয়া হল। বিস্তারিত জানতে উপরে উল্লিখিত সাইটে যেতে হবে।