একটি রেগুলার এক্সপ্রেশন (বা Regex) হলো ক্যারেক্টারের একটি ক্রম, যা দিয়ে আমরা স্ট্রিংয়ের নির্দিষ্ট কিছু এলিমেন্ট লক্ষ্য করতে ও সেগুলো নিয়ে কাজ করতে পারি। তাই আমরা করতে পারি:
💡 JavaScript-এর রেগেক্স ফ্লেভার ভাষাটির ECMA-262 স্ট্যান্ডার্ডের অংশ। এর মানে হলো, ব্রাউজার-নির্দিষ্ট কম্প্যাটিবিলিটি নিয়ে আপনাকে ভাবতে হবে না।
JavaScript-এ রেগুলার এক্সপ্রেশন সাধারণত /pattern/modifiers ফরম্যাটে লেখা হয়।
রেগুলার এক্সপ্রেশন তৈরির দুটি উপায় আছে:
const regex = /[a-z]/;
const regex = new RegExp('[a-z]');
দুটি ক্ষেত্রেই JavaScript রেগেক্স থেকে একটি অবজেক্ট তৈরি করে। ডিফল্ট হিসেবে লিটারাল নিয়ে ইমিউটেবল প্যাটার্ন ব্যবহার করার পরামর্শ দেওয়া হয়।
যেসব ক্ষেত্রে রেগেক্স বদলাবে বা আমরা এখনো তা জানি না (যেমন কোনো ইনপুট), সেখানে RegExp কনস্ট্রাক্টর ব্যবহার করা যেতে পারে।
রেগুলার এক্সপ্রেশনের flags নামের ঐচ্ছিক সুপারপাওয়ার আছে, যা বাড়তি ফিচার ব্যবহারের সুযোগ দেয়।
বেশ জনপ্রিয় কিছু ফ্ল্যাগ হলো:
/g - গ্লোবাল সার্চ/i - কেস ইনসেনসিটিভ/m - মাল্টিলাইন সার্চএখানে একটি সহজ উদাহরণ:
const re = /home/gi;
const str = 'Home, sweet home.';
const myArray = str.match(re);
console.log(myArray);
=> // ["Home", "home"]
g ক্যারেক্টারটি স্ট্রিংয়ের ভেতরে সম্ভাব্য সব ম্যাচ পার্স করার সুযোগ দেয়। এই ফিচারটি ছাড়া JavaScript কেবল প্রথম Home ম্যাচটিই এক্সট্র্যাক্ট করত।
কেস ইনসেনসিটিভ ফ্ল্যাগ /i কোনো প্যাটার্ন খোঁজার সময় আমাদের নমনীয় হতে দেয়। এভাবে আমরা যা খুঁজছি সেটি UPPERCASE-এ লেখা হোক বা lowercase-এ, কিছু যায় আসে না।
RegExp কনস্ট্রাক্টর ব্যবহার করার সময় ফ্ল্যাগ যোগ করার সিনট্যাক্স আলাদা।
let regex = /[a-z]/gi; // literal notation
let regex = new RegExp('[a-z]', 'gi'); // constructor with string pattern as first argument
let regex = new RegExp(/[a-z]/, 'gi'); // constructor with regular expression literal as first argument (Starting with ECMAScript 6)
JavaScript-এর বর্তমান বিল্ট-ইন ফাংশনগুলোর সাথে রেগুলার এক্সপ্রেশন মিলিয়ে ব্যবহার করলে স্ট্রিং থেকে ডেটা বের করা ও তা নিয়ে কাজ করার বেশ শক্তিশালী সব উপায় হাতে আসে।
রেগেক্সের সাথে ব্যবহৃত সবচেয়ে কমন কিছু ফাংশন নিচে দেওয়া হলো।
test() মেথডটি একটি রেগুলার এক্সপ্রেশন ও নির্দিষ্ট একটি স্ট্রিংয়ের মধ্যে ম্যাচ আছে কি না তা সার্চ করে। এটি ট্রু বা ফলস রিটার্ন করে।
const str = 'It is difficult to test if you have a virus';
const result = /virus$/.test(str);
console.log(result);
// => true
match() মেথড দিয়ে আমরা একটি দরকারি অ্যারে পাই, যার ভেতরের এলিমেন্ট নির্ভর করে খুঁজে পাওয়া ম্যাচগুলো আছে কি নেই তার উপর।
এভাবে আমরা যেকোনো স্ট্রিং থেকে তথ্য সার্চ ও এক্সট্র্যাক্ট দুটোই করতে পারি। যেমন:
const funnyQuote =
'If you see someone crying, ask if it is because of their haircut.';
const regex1 = /someone/;
const regex2 = /happy/;
funnyQuote.match(regex1);
// => ["someone", index: 11, input: "If you see someone crying, ask if it is because of their haircut.", groups: undefined]
funnyQuote.match(regex2);
// => null
গ্লোবাল সার্চ ফ্ল্যাগ /g থাকলে মেথডটি কেবল একটি ম্যাচ আর তার সাথে index বা input-এর মতো দরকারি তথ্য না দিয়ে অ্যারেতে থাকা সব ম্যাচ রিটার্ন করে:
const funnyQuote =
'If you see someone crying, ask if it is because of their haircut.';
const regex3 = /if/gi;
funnyQuote.match(regex3);
// => ["If", "if"];
JavaScript-এর replace() মেথড দিয়ে আমরা কোনো নির্দিষ্ট স্ট্রিংয়ের ভেতরে একটি মান খুঁজে সেটিকে পছন্দের নতুন একটি মান দিয়ে রিপ্লেস করতে পারি।
string.replace(searchValue, newValue);
যে প্যাটার্ন দিয়ে প্রতিস্থাপনটি খোঁজা হবে, সেটি একটি সাধারণ স্ট্রিং বা একটি রেগুলার এক্সপ্রেশন হতে পারে।
let string = 'I like dogs!';
let result = string.replace('dogs', 'cats');
let string = 'I would love to travel to Japan';
let result = string.replace(/Japan/g, 'Hawaii');
এর বাইরে, প্রতিটি মানে বাড়তি পরিবর্তন আনতে আমরা রিপ্লেসমেন্টের জায়গায় একটি ফাংশনও দিতে পারি।
let text = 'Say hello to the chatbot.';
let result = text.replace(/chatbot|hello/gi, function (word) {
return word.toUpperCase();
});
// => "Say HELLO to the CHATBOT"
JavaScript-এর split() মেথড রেগুলার এক্সপ্রেশন দিয়ে স্ট্রিং নিয়ে কাজ করার আরেকটি ভিন্ন উপায়।
এখানে আমরা একটি প্যাটার্ন চিনে নিয়ে নির্দিষ্ট একটি স্ট্রিং ভাগ করতে রেগেক্স ব্যবহার করি, যেমন str.split(/[,.\s]/)। এই প্যাটার্নটিই separator হিসেবে কাজ করে।
const str = 'hello,user.how are.you';
const result = str.split(/[,.\s]/);
console.log(result);
// => ['hello', 'user', 'how', 'are', 'you']
আপনাকে একটি কোম্পানিতে রেগুলার এক্সপ্রেশন স্পেশালিস্ট হিসেবে নিয়োগ দেওয়া হয়েছে, যেখানে একটি চ্যাটবট তৈরি করা হচ্ছে।
এটি এখনও উন্নয়নের একেবারে প্রাথমিক পর্যায়ে আছে, তাই আপনার লক্ষ্য হলো রেগুলার এক্সপ্রেশন ব্যবহার করে প্রাকৃতিক ভাষা বোঝা ও তৈরি করার ক্ষেত্রে চ্যাটবটের দক্ষতা বাড়ানো।
বুদ্ধিমান হওয়ার পাশাপাশি চ্যাটবট একজন বিশ্বস্ত সহকারীও।
চ্যাটবটকে কিছু জিজ্ঞাসা করার জন্য ব্যবহারকারীকে কমান্ডের প্রথমেই “Chatbot” শব্দটি বলতে হবে।
কিওয়ার্ডটি বড় হাতের অক্ষরে লেখা হবে নাকি ছোট হাতের অক্ষরে, তা গুরুত্বপূর্ণ নয়। এখানে গুরুত্বপূর্ণ হলো শব্দটির অবস্থান।
isValidCommand() ফাংশনটি ইমপ্লিমেন্ট করুন, যা ব্যবহারকারী কখন কমান্ড দিচ্ছেন তা চ্যাটবটকে চিনতে সাহায্য করে।
isValidCommand("Chatbot, play a song from the 80's.";
// => True
isValidCommand("Hey Chatbot, where is the closest pharmacy?";
// => False
isValidCommand("CHATBOT, do you have a solution for this challenge?";
// => True
মানুষ কীভাবে তাদের অনুভূতি প্রকাশ করতে ইমোজি ব্যবহার করে, তা বুঝতে চ্যাটবটের বেশ অসুবিধা হয়।
চ্যাটবট যখন ব্যবহারকারীর মেসেজ পায়, তখন প্রতিটি ইমোজি “emoji” হিসেবে এবং তারপর তার id নম্বর হিসেবে লেখা থাকে।
এমন একটি removeEmoji() মেথড ইমপ্লিমেন্ট করুন যা একটি স্ট্রিং নেয় এবং পুরো মেসেজ থেকে ইমোজির সব এনক্রিপশন সরিয়ে দেয়।
যেসব লাইনে ইমোজির লেখা নেই, সেগুলো অপরিবর্তিত অবস্থায় রিটার্ন করতে হবে।
শুধু ইমোজি স্ট্রিংটি সরিয়ে ফেলুন। হোয়াইটস্পেস ঠিক করার চেষ্টা করবেন না।
এই নির্দিষ্ট চ্যালেঞ্জের জন্য রেগুলার এক্সপ্রেশন তৈরি করতে কনস্ট্রাক্টর সিনট্যাক্স ব্যবহার করুন।
removeEmoji("I love playing videogames emoji3465 it's one of my hobbies");
// => "I love playing videogames it's one of my hobbies"
চ্যাটবটের ফিচার মোবাইল অ্যাপে ডাউনলোড করার সুবিধার কথা মাথায় রেখে, কথোপকথনের সময় ব্যবহারকারী একটি ফোন নম্বর লিখবেন বলে ধরে নেওয়া হয়।
সমস্যা হলো, চ্যাটবট শুধু একটি নির্দিষ্ট ফরম্যাটের নম্বরই পড়তে ও যাচাই করতে পারে।
নম্বরটি বৈধ হলে (অর্থাৎ রেগুলার এক্সপ্রেশন দ্বারা নির্দিষ্ট করা ক্যারেক্টার সিকোয়েন্সের সাথে মিললে), চ্যাটবট ব্যবহারকারীকে ধন্যবাদ জানিয়ে এবং নম্বরটি নিশ্চিত করে একটি মেসেজ দেয়। আর নম্বরটি অবৈধ হলে ফাংশনটি ব্যবহারকারীকে জানায় যে ফোন নম্বরটি বৈধ নয়।
প্রত্যাশিত ফরম্যাট হলো: (+##) ###-###-###
checkPhoneNumber('(+34) 659-771-594');
// => "Thanks! You can now download me to your phone."
checkPhoneNumber('659-771-594');
// => "Oops, it seems like I can't reach out to 659-771-594"
চ্যাটবট সত্যিই একটি কৌতূহলী সফটওয়্যার। কোনো নির্দিষ্ট বিষয়ে সে ইন্টারনেটে সার্চ করতে পারলেও, প্রাসঙ্গিক তথ্য খুঁজে বের করার জন্য ব্যবহারকারীদের কাছে দারুণ সব ওয়েবসাইট বা URL-এর খোঁজ নিতে ভালোবাসে।
কথোপকথনের উদাহরণ:
getURL() ফাংশনটি ইমপ্লিমেন্ট করুন, যা শুধু প্রতিটি ওয়েবসাইটের লিংক নিয়ে একটি অ্যারে রিটার্ন করতে পারে। যেকোনো URL চিনতে একটি রেজেক্স লেখা খুবই জটিল হবে, কিন্তু চ্যাটবটের শুধু সাধারণ URL পড়ার দরকার। এই অনুশীলনীর জন্য, URL হলো "." দিয়ে আলাদা করা শব্দের যেকোনো ক্রম।
getURL(
'I learned a lot from exercism.org and developer.mozilla.org, but I found ts39.es very boring!',
);
// => ["exercism.org", "developer.mozilla.org", "ts39.es"];
যারা চ্যাটবটের সাথে কথোপকথন করেছে, তাদের সবার ডেটা সংরক্ষণ করার জন্য চ্যাটবট ব্যবহারকারীর প্রোফাইল থেকে পুরো নামটি এ ধাঁচে পেতে পারে: “smith, john”।
এভাবেই আমরা চাই আমাদের চ্যাটবট যেন সত্যিই ভদ্র হয় এবং ভালো ছাপ ফেলে।
niceToMeetYou() ফাংশনটি লিখুন, যা ব্যবহারকারীর পুরো নাম নিয়ে একটি স্ট্রিং নেয় এবং “Nice to meet you, John Smith” স্ট্রিংটি রিটার্ন করে।
শেখার উদ্দেশ্যে, রেগুলার এক্সপ্রেশনের একটি রিপ্লেসমেন্ট মেথড ব্যবহার করে ফাংশনটি ইমপ্লিমেন্ট করুন।
let str = 'Smith, John';
niceToMeetYou(str);
// => "Nice to meet you, John Smith"
Exercism-এ সাইন আপ করুন, JavaScript ট্র্যাকের 37টি কনসেপ্ট159টি অনুশীলনী আর সত্যিকারের মানুষের মেন্টরিং দিয়ে শিখুন ও দক্ষ হয়ে উঠুন, সম্পূর্ণ বিনামূল্যে।