Tag Archives: রেগুলার এক্সপ্রেশনে

রেগুলার এক্সপ্রেশন -এ শুরু।

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

রেগুলার এক্সপ্রেশন ব্যপারটা কি? সহজ কথায় রেগুলার এক্সপ্রেশন হচ্ছে কতোগুলা প্যাটার্ন বা বর্ণ বিন্যাস যার মাধ্যমে আমরা স্ট্রিং থেকে আমাদের প্রত্যাশিত সাব-স্ট্রিং বা ক্ষুদ্র অক্ষর বিন্যাস খুঁজে বের করতে পারি। কিছু ব্যতিক্রম বাদে মোটামুটি সব প্রোগ্রামিং ভাষায় রেগুলার এক্সপ্রেশনের নিয়মকানুন একই। এই লিখায় আমি মূলত জাভাস্ক্রিপ্ট ব্যবহার করবো। নিচের স্ট্রিং-কে আমরা গিনিপিগ হিসেবে নিলাম।

Mr. Alu and mr. Potol are friends since 2008. They study at the same university in the session 2008-2009.

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

রেগুলার এক্সপ্রেশনের গুরুত্বপূর্ণ যে বিষয়টি খেয়াল রাখতে হবে সেটি হচ্ছে এটি কাজ করে ক্যারেক্টার বাই ক্যারেক্টার অর্থাৎ প্যাটার্ন এর যদি প্রথম ক্যারেক্টার-এ মিল পায় তবেই শুধু এর (প্যাটার্নটির) দ্বিতীয় ক্যারেক্টার নিয়ে অগ্রসর হবে অন্যথায় আবার প্যাটার্নটির প্রথম ক্যারেক্টার থেকে শুরু করবে । যেহেতু আমরা শুধু একটি মাত্র ক্যারেক্টার M কে চেক করবো এবং এর আগে পরে কিছু নাই সুতরাং আমাদের প্যাটার্নটি হবে খুবই সহজ অর্থাৎ শুধু M

var str = 'Mr. Alu and mr. Potol are friends since 2008. They study at the same university in the session 2008-2009.';
var pattern = /M/;
var matches = str.match(pattern);
console.log(matches);

/* Output in console*/
 ["M"]

অনুরপভাবে যদি Mr কে বের করতে চাই তবে প্যাটার্নটি হবে Mr অথবা 2008 কে বের করার জন্যে প্যাটার্নটি 2008। যেহেতু ক্যারেক্টার বাই ক্যারেক্টার মিল খুঁজে, তাই Mr প্যাটার্নটির ক্ষেত্রে প্রথমে M কে খুঁজবে, যদি পেয়ে যায় তবে আমাদের গিনিপিগ স্ট্রিং-এ প্যাটার্নটির পরবর্তী ক্যারেক্টার r কে খুঁজবে ঠিক M-এর পরে। যদি মিল পেয়ে যায় তাহলে কাজ শেষ। যদি মিল না পায় তাহলে আবার প্রথম থেকে প্যাটার্নটির M দিয়ে শুরু করবে গিনিপিগ স্ট্রিং-এর বাকি ক্যারেক্টারগুলোকে চেক করার জন্যে এবং এভাবে চলতে থাকে গিনিপিগ স্ট্রিং-এর শেষ ক্যারেক্টার পর্যন্ত।  সাধারণভাবে কিছু বিশেষ ক্যারেক্টারবাদে প্রতিটি ক্যারেক্টারকে লিটার‍্যালি বা আক্ষরিকভাবেই বিবেচনা করা হয় যাদের নিয়ে আমরা ধীরে ধীরে আলোচনা করবো।

আচ্ছা, আমাদের গিনিপিগ স্ট্রিং-এ কোনো বছর আছে কিনা আমরা দেখতে চাই। আমরা ধরে নেই, বছর মানে চারটা সংখ্যা পাশাপাশি থাকবে কিন্তু ক্যারেক্টারটি যে সংখ্যা তা ডিফাইন করবো কিভাবে? খুব সহজ, গণিতে যেই রকম আমরা সেট ব্যবহার করি, ঠিক সেই রকম আমরা ক্যারেক্টার সেট বলে দিতে পারি। যাকে রেগুলার এক্সপ্রেশন-এ ক্যারেক্টার সেট বা ক্যারেক্টার ক্লাস বলে। ক্যারেক্টার সেট ডিক্লায়ের করার নিয়ম হলো স্কোয়ার অর্থাৎ [] বন্ধনীর ভিতরে প্রয়োজনীয় ক্যারেক্টারগুলো দিয়ে দেয়া। যেমন,  [0123456789] মানে সংখ্যার সেট, BCDEF] হলো ABCDEF-এর সেট। চাইলে আমরা রেঞ্জ দিয়ে সংক্ষেপে লিখেতে পারি। রেঞ্জ বুঝানোর জন্যে ড্যাশ (-) ব্যবহার করা হয়। যেমন, [0-9] মানে সংখ্যার সেট যা [0123456789] এর অনুরুপ অথবা -zA-Z] মানে ইংরেজি অ্যালফাবেটের সেট। সেপারেটর হিসেবে কমা দেবার প্রয়োজন নাই। আবার নেগেটিভ সেটও তৈরি করা যায় শুরুতে একটা ^ বসিয়ে দিয়ে। যেমন, [^0-9] মানে সংখ্যা বাদে সকল কিছুর সেট।

শুধু মনে রাখতে হবে রেগুলার এক্সপ্রেশন-এ সেটটি একটি একক ক্যারেক্টার হিসেবে বিবেচনা করা হবে অর্থাৎ ক্যারেক্টার সেট মূলত অন্যান্য সাধারণ ক্যারেক্টার মতই জায়গা দখল করবে। তো বের করে ফেলি আমাদের বছর বের করার প্যাটার্ন। আমাদের দরকার পর পর চারটা সংখ্যা অর্থাৎ আমাদের সংখ্যার সেটটি পর পর চার বার দিলেই হবে। তার মানে প্যাটার্নটি হলো  [0-9][0-9][0-9][0-9]

var str = 'Mr. Alu and mr. Potol are friends since 2008. They study at the same university in the session 2008-2009..';
var pattern = /[0-9][0-9][0-9][0-9]/;
var matches = str.match(pattern);
console.log(matches);

/* Output in console*/
 ["2008"]

উপড়ের প্যাটার্নটিতে কিসের যেন অভাব!  একই জিনিষ চারবার করে লিখা, দেখতে ভালো লাগছে না। একটু ঘষামাজা করা দরকার আর ঘষামাজা করার জন্যে যা লাগবে, তাকে রেগুলার এক্সপ্রেশন -এ বলে কোয়ান্টিফায়ার। এই কোয়ান্টিফায়ার হচ্ছে কতগুলো স্পেশাল ক্যারেক্টার যা দিয়ে আমরা একই জিনিস বার বার না লিখে তার পরিবর্তে কোয়ান্টিফায়ার ক্যারেক্টার দিয়ে দিতে পারি। যেমন, * মানে ০ থেকে অগণিত, + মানে ১ থেকে অগণিত, ? মানে ০ থেকে ১ ইত্যাদি। আবার আমরা চাইলে নিজেরাও রেঞ্জের মান বলে দিতে পারি। রেঞ্জের মান ডিফাইন করার নিয়ম হচ্ছে কারলি অর্থাৎ {} ব্রাকেটের মধ্যে শুরু ও শেষ বলে দেয়া। যেমন, {0,4} মানে হচ্ছে ০ থেকে চার, {1,5} মানে হচ্ছে ১ থেকে পাঁচ ইত্যাদি। মজার ব্যপার হচ্ছে রেঞ্জের শেষের মান না দিলে তার মান হবে অগণিত। যেমন, {0,} মানে হচ্ছে ০ থেকে অগণিত। আবার যদি রেঞ্জ না দিয়ে শুধুমাত্র একটি মান দেই তাহলে তার মানে দাড়ায় ঠিক ততটা। যেমন, {2} মানে হচ্ছে ঠিক দুইটা। প্রকৃতপক্ষে কোয়ান্টিফায়ার ক্যারেক্টারগুলো অর্থাৎ *,+,? কোয়ান্টিফায়ার রেঞ্জের সংক্ষিপ্তরূপ। যেমন, {1,} এর সমান হচ্ছে + আবার {o,} এর সমান হচ্ছে *। নিচের কোয়ান্টিফায়ারের তালিকাটি খেয়াল করলে আরও পরিস্কার বোঝা যাবেঃ

কোয়ান্টিফায়ারমানবিকল্প
*০ থেকে অগণিত {0,}
+১ থেকে অগণিত {1,}
?০ থেকে ১ অর্থাৎ থাকতে পারে আবার নাও পারে{০,1}
{1,5}১ থেকে পাঁচ 
{5}ঠিক পাঁচটা 

এবার তাহলে কোয়ান্টিফায়ার ব্যবহার করে বছর বের করার প্যাটার্নটি লিখা যাক যা দেখতে আগের চেয়ে অনেক ভাল লাগবে।

var str = 'Mr. Alu and mr. Potol are friends since 2008. They study at the same university in the session 2008-2009.';
var pattern = /[0-9]{4}/;
var matches = str.match(pattern);
console.log(matches);

/* Output in console*/
 ["2008"]

আমি জানি এখন একটি ব্যাপার অনেকের মাথায় ঘুরছে সেটা হলো যদি বিল্ট-ইন কোয়ান্টিফায়ারের সংক্ষিপ্তরূপ মানে * ,+ ইত্যাদি থাকে, তাহলে বিল্ট-ইন ক্যারেক্টার সেট বা ক্যারেক্টার ক্লাস থাকা উচিত কেননা সংখ্যার সেট বা অ্যালফাবেটিক  সেট এরকম কিছু সেট আছে যেগুলা আগে থেকেই নির্দিষ্ট। তাদের ধারনা একদম ঠিক, কোয়ান্টিফায়ারের মতো কিছু বিল্ট-ইন ক্যারেক্টার সেট আছে যা শুরু হয় ব্যাকওয়ার্ড স্লাস অর্থাৎ \।  যেমন, \d মানে সংখ্যার সেট, \w মানে অ্যালফাবেটিক ও আন্ডারস্কোর (_) এর সেট ইত্যাদি। নিচের একটি সংক্ষিপ্ত তালিকা দিয়ে দিলামঃ

ক্যারেক্টার সেটক্যারেক্টারসমূহবিকল্প
\dসকল সংখ্যা [0-9]
\D সংখ্যা বাদে সকল কিছুর সেট [^0-9]
\wঅ্যালফাবেটিক ও আন্ডারস্কোর (_) এর সেট [a-zA-Z_]
\Wঅ্যালফাবেটিক ও আন্ডারস্কোর (_) বাদে সেট [^a-zA-Z_]
\s হোয়াইট স্পেস ক্যারেক্টারসমূহ যেমন স্পেস, ট্যাব 
\Sহোয়াইট স্পেস বাদে সকল কিছুর সেট 
 \tশুধু ট্যাব এর সেট 

বিল্ট-ইন ক্যারেক্টার সেট ব্যবহার করে এখন আমরা আমদের বছর বের করার প্যাটার্নটি আরও স্মার্ট ও সংক্ষিপ্ত করে ফেলি যা হবে নিম্নরূপঃ

var str = 'Mr. Alu and mr. Potol are friends since 2008. They study at the same university in the session 2008-2009.';
var pattern = /\d{4}/;
var matches = str.match(pattern);
console.log(matches);

/* Output in console*/
 ["2008"]

লেখাটি আর সংক্ষেপ থাকছে না তাই এখানেই শেষ করছি। এখনো রেগুলার এক্সপ্রেশনের আরও কিছু জিনিস বাকি আছে যেমন, গ্রিডি/নন-গ্রিডি কোয়ান্টিফায়ার, মডিফায়ার, ক্যাপচারিং গ্রুপ, লুক অ্যাহেড এবং কিছু পজিশনিং ক্যারেক্টার যা পরবর্তী লেখাতে আলোচনা করবো। তবে শেষ করবো একটি বিশেষ ক্যারেক্টার দিয়ে, যেটি হচ্ছে ডট (.)। রেগুলার এক্সপ্রেশনে ডট মানে বুঝায় নতুন লাইন বাদে যেকোনো ক্যারেক্টার । যেমন, a. মানে, a এর পরে যেকোনো একটি ক্যারেক্টার বুঝায়।  তাহলে .* দিয়ে কি বুঝায় তা ভাবতে দিয়ে আমি বিদায় নিলাম।

দ্বিতীয় পর্বের লিঙ্ক