আপনি RegEx শুনে থাকতে পারেন, যা রেগুলার এক্সপ্রেশনের সংক্ষিপ্ত রূপ। এটি প্রথমে ভয়াবহ লাগতে পারে, কিন্তু প্যাটার্নগুলোর অর্থ এবং কীভাবে একটি এক্সপ্রেশন তৈরি ও ব্যবহার করবেন সেটি অভ্যাস হয়ে গেলে সেটা খারাপ নয়। স্ট্রিং এবং টেক্সটকে আরও বিমূর্তভাবে চিন্তা করার অভ্যাস হয়ে গেলে, এটি ডেটার সেটে সাধারণ প্যাটার্ন খুঁজে বের করার সমস্যা সমাধানে একটি উপকারী টুল হতে পারে।
RegEx হলো প্যাটার্ন ম্যাচিংয়ের একটি পদ্ধতি: একটি প্যাটার্নের ভিত্তিতে স্ট্রিং বা টেক্সট ফিল্টার করার উপায়, সাধারণত望ম টেক্সট বের করে সংশোধন করার জন্য। এই নিবন্ধে আমরা রেগুলার এক্সপ্রেশন কীভাবে ব্যবহার করবেন এবং রুবি মেথড ব্যবহার করে সেগুলো কীভাবে টেস্ট করবেন তা আলোচনা করব যাতে আপনার প্রজেক্টের লজিকে সেগুলো অন্তর্ভুক্ত করতে পারেন।
RegEx ভিজ্যুয়ালাইজ এবং বোঝার জন্য একটি অত্যন্ত উপকারী টুল হলো Rubular নামক সাইট। এখানে ক্লিক করে ইতিমধ্যে পপুলেট করা টেক্সট ব্লক ব্যবহার করে RegEx টেস্ট করুন। আপনি দেখবেন দুটি ফরোয়ার্ড স্ল্যাশের মাঝপথে 'neighbor' শব্দটি আছে।
বিশ্বাস করুন বা না করুন, এটি একটি রেগুলার এক্সপ্রেশন! পুরো শব্দ, বাক্য, অনুচ্ছেদ এমনকি টেকনিক্যালি রেগুলার এক্সপ্রেশন বলা যায় (যতক্ষণ না দুটি ফরোয়ার্ড স্ল্যাশের মাঝপথে থাকে)। Rubular এনভায়রনমেন্ট আমাদের টেক্সট ব্লকে 'neighbor' প্যাটার্নের প্রতিটি উদাহরণ হাইলাইট করে — এমনকি যেখানে neighbor একটি বড় শব্দের অংশও! কিন্তু আপনি কোনো নির্দিষ্ট শব্দ ম্যাচের চেয়ে আরও বিমূর্ত কিছু খুঁজতে চাইতে পারেন। এখানেই মেটাক্যারেক্টারগুলো কাজে আসে।
মেটাক্যারেক্টার
অনুভবী প্রোগ্রামারদের জন্যও RegEx ব্যবহার করা চ্যালেঞ্জিং হতে পারে, তাই হতাশ হওয়ার দরকার নেই।
যেভাবে পরমাণু আমাদের চারপাশের সব কিছুর বিল্ডিং ব্লক, তেমনি মেটাক্যারেক্টার রেগুলার এক্সপ্রেশনের বিল্ডিং ব্লক। আপনার রেগুলার এক্সপ্রেশনে জোড়া দিচ্ছেন সাথে সাথে পুরো প্যাটার্ন পরিবর্তন হয়। এবং পুরো প্যাটার্ন পরিবর্তন হলে, আপনি যে মেথডগুলো ব্যবহার করছেন তাদের ফলাফলও ভিন্ন হতে পারে।
নিচে আপনার রেগুলার এক্সপ্রেশন মডিফাই করার একাধিক উপায় দেওয়া হলো যাতে আপনার জন্য কাজ করার প্যাটার্ন খুঁজে পান। ফোন নম্বর বা ইমেইল এর জন্য রেগুলার এক্সপ্রেশন লেখার কোনো একমাত্র সঠিক উপায় নেই — এটা সম্পূর্ণরূপে আপনার প্রজেক্টের প্রয়োজনের ওপর নির্ভর করে।
| মেটাক্যারেক্টার | ম্যাচ করে | উদাহরণ |
|---|---|---|
| [abc] | স্ট্রিং-এ a, b বা c যেকোনো একক ক্যারেক্টার ম্যাচ করে | /[eig]/ neighbor, apple, বা gate-এর অংশ ম্যাচ করতে পারে |
| [^abc] | নিগেটেড ক্যারেক্টার ক্লাস যা a, b বা c ছাড়া স্ট্রিং-এর প্রতিটি ক্যারেক্টার ম্যাচ করে | /[^eig]/ neighbor, apple, বা gate-এর অংশ ম্যাচ করতে পারে |
| [a-z] | a-z রেঞ্জের যেকোনো একক ক্যারেক্টার ম্যাচ করে | /[e-i]/ neighbor, apple, বা gate-এর অংশে একক ক্যারেক্টার ম্যাচ করতে পারে |
| [a-zA-Z] | a-z বা A-Z রেঞ্জের ক্যারেক্টার ম্যাচ করে | /[e-i]/ "Hi neighbor!", Grapple, বা gate-এর অংশে একক ক্যারেক্টার ম্যাচ করতে পারে |
| ^ | লাইন শুরু | /^Hello/ 'Hello' দিয়ে শুরু হওয়া লাইন ম্যাচ করে |
| $ | লাইন শেষ | /Goodbye$/ 'Goodbye' দিয়ে শেষ হওয়া লাইন ম্যাচ করে |
| \A | স্ট্রিং শুরু। '^' এর মতো কিন্তু নো মাল্টিলাইন মোড | /\Aa/ 'apple'-এর 'a' ম্যাচ করে, কিন্তু 'apricot'-এর 'a' নয় কারণ সেটি স্ট্রিং শুরু নয় |
| \z | স্ট্রিং শেষ। '$' এর মতো কিন্তু নো মাল্টিলাইন মোড | /\za/ 'zebra'-এর 'a' ম্যাচ করে, কিন্তু 'libra'-এর 'a' নয় কারণ সেটি স্ট্রিং শেষ নয় |
| . | ওয়াইল্ড কার্ড। ডট যেকোনো ক্যারেক্টার ম্যাচ করে | /./ 'apple'-এ যেকোনো একক ক্যারেক্টার ম্যাচ করবে |
| + | পূর্বের মেটাক্যারেক্টারের এক বা অধিক ম্যাচ করে | /aa+/ 'aa', 'aaaaaaa' ম্যাচ করবে কিন্তু 'a' নয় কারণ পূর্বের মেটাক্যারেক্টারের (যা এখানে দ্বিতীয় a) এক বা অধিক থাকতে হবে |
| * | পূর্বের মেটাক্যারেক্টারের শূন্য বা অধিক ম্যাচ করে | /ab*/ 'a', 'ab', 'abbbbbb' ম্যাচ করবে |
| \s | যেকোনো হোয়াইটস্পেস ক্যারেক্টার | /^The\s.+s$/ 'The Beatles', 'The Rolling Stones', 'The Cranberries' ইত্যাদি ম্যাচ করবে |
| \S | যেকোনো নন-হোয়াইটস্পেস ক্যারেক্টার | /\S+/ 'The Beatles', 'The Rolling Stones', 'The Cranberries' ইত্যাদি ম্যাচ করবে |
| \d | যেকোনো ডিজিট | /\d+/ 22, 33333, 0 ইত্যাদি ম্যাচ করবে |
| \D | যেকোনো নন-ডিজিট | /\D+/ 'Hello, goodbye' ম্যাচ করবে |
| \w | যেকোনো ওয়ার্ড ক্যারেক্টার | /ny\w*/ 'ny_152', 'nypost39' ইত্যাদি ম্যাচ করবে |
| \W | যেকোনো নন-ওয়ার্ড ক্যারেক্টার | /\W+/ ')(*&^%$' ম্যাচ করবে |
| a{3} | ঠিক ৩টি 'a' | /\d{3}-\d{3}-\d{4}/ 555-555-5555 ম্যাচ করবে |
| a{3,} | ৩ বা অধিক 'a' | /[a-zA-Z0-9!#$^&*())]{8,}/ 'xE*BqRx14B7TAQp' ম্যাচ করবে ⇐ যা পাসওয়ার্ডের মতো দেখে |
| a{3,6} | ৩ থেকে ৬টি 'a' | /[a-zA-Z0-9!#$^&*())]{8,32}/ '0XX!pC3Odpu30Qc' ম্যাচ করবে কারণ এটা ৩২ ক্যারেক্টার এর কম এবং ৮ এর বেশি |
| a? | ০ বা ১টি 'a' | /\d?-\d{3}-\d{3}-\d{4}/ ইন্টারন্যাশনাল কোডসহ এবং সেটি ছাড়া ফোন নম্বর ম্যাচ করবে |
মেটাক্যারেক্টার ব্যবহার করা ওয়েবসাইটে ফর্ম পূরণের সময় ভ্যালিডেশনের জন্য চমৎকার। আমরা চাই সঠিক তথ্য দেওয়া হয়েছে — এড্রেস, ইমেইল বা ফোন নম্বরের প্যাটার্ন সঠিক ফরম্যাটে কিনা তা নিশ্চিত করতে RegEx ব্যবহার করা একটি চমৎকার উদাহরণ। এতে কম ইউজার এরর সহ আরও সুবিন্যাস ডেটাবেস তৈরি হয় নতুন অ্যাকাউন্ট রেজিস্টার করার সময়।
রুবিতে RegEx টেস্ট করার মেথড
scan এবং match-এর পার্থক্য বোঝার জন্য আমরা যে কোডটি ব্যবহার করব:
#!/usr/bin/ruby
class RegexTest
def initialize(str, regex)
@str = str
@regex = regex
@result = str.scan(regex)
end
def display_details()
puts "String = #@str"
puts "regex = #@regex"
puts "result = #@result"
end
end
# Create Objects
str1 = RegexTest.new("The rain in Spain stays mainly on the plain", /\w+ain/)
str2 = RegexTest.new("In Hertford, Hereford, and Hampshire, hurricanes hardly ever happen", /H\w+/)
# Call Methods
str1.display_details()
str2.display_details()
Scan
রুবিতে scan মেথড আপনার রেগুলার এক্সপ্রেশন সাথে মেলা সব স্ট্রিং-এর একটি অ্যারে রিটার্ন করে:
str1: result = ["rain", "Spain", "main", "plain"]
str2: result = ["Hertford", "Hereford", "Hampshire"]
এটি আপনাকে ফলাফলের সাথে যা ইচ্ছা করতে দেয়।
RegExp Match
রেগুলার এক্সপ্রেশন Match মেথড scan-এর সাথে খুব মিলিত, কিন্তু সব ম্যাচের বদলে ম্যাচের প্রথম উদাহরণ খুঁজে বের করে। @result = str.scan(regex) কে @result = str.match(regex) বদলে পার্থক্য দেখুন:
str1: result = rain
str2: result = Hertford
Match কিন্তু একটি <Matchdata> অবজেক্ট রিটার্ন করে। এর সাথে কিছু মেথড জড়িত যা আপনি ফলাফল ব্যবহার করার সময় আপনার লজিকে ব্যবহার করতে পারেন। আরও তথ্যের জন্য রুবি ডক্স দেখুন।
Grep
Grep হলো অ্যারেতে মেলা স্ট্রিং খুঁজে বের করার একটি ইনামারেবল মেথড। এটি আপনার রেগুলার এক্সপ্রেশন সাথে মেলা সব স্ট্রিং-এর একটি অ্যারে রিটার্ন করে। আমাদের কোডে, আমাদের পাস করা স্ট্রিংটি অ্যারেতে বিভক্ত করা নিশ্চিত করতে হবে।
এই লাইনটি পরিবর্তন করুন:
@result = str.match(regex)
এবং এটিকে পরিবর্তন করুন:
@result = str.split(/\s|,/).grep(regex);
"Career Karma আমার জীবনে ঢুকেছিল যখন আমার সেটি সবচেয়ে বেশি দরকার ছিল এবং দ্রুত একটি বুটক্যাম্পের সাথে মিলিয়ে দিয়েছিল। গ্র্যাজুয়েট হওয়ার দুই মাস পর আমি আমার স্বপ্নের চাকরি পেয়েছিলাম যা আমার মূল্যবোধ এবং লক্ষ্যের সাথে মিলে যেত!"
— ভেনাস, সফটওয়্যার ইঞ্জিনিয়ার, রকবট
তখন আপনি প্রথম ফলাফলের মতো একটি ফলাফল পাবেন:
str1: result = ["rain", "Spain", "main", "plain"]
str2: result = ["Hertford", "Hereford", "Hampshire"]
Str =~ RegEx
=~ বেসিক ম্যাচিং অপারেটর ব্যবহার করে আমরা স্ট্রিংকে রেগুলার এক্সপ্রেশন সাথে তুলনা করে ম্যাচের প্রথম ইনডেক্স রিটার্ন করতে পারি। যদি কোনো ম্যাচ না থাকে তবে nil রিটার্ন করবে।
উপসংহার
এই নিবন্ধে আমরা রুবিতে রেগুলার এক্সপ্রেশন (RegEx) কীভাবে ব্যবহার করবেন তা আলোচনা করেছি। আপনি যদি রুবি দিয়ে কী কী বানানো যায় তা জানতে চান, তবে আমাদের আর্টিকেল "What Is Ruby Code Used For?" পড়ুন।
রুবি শিখার আরও ভালো উপায় চান? Career Karma আপনাকে সেরা ট্রেনিং প্রোগ্রাম খুঁজে দিতে সাহায্য করবে।