রেগুলার এক্সপ্রেশন কি?
রেগুলার এক্সপ্রেশন, যা regex নামেও পরিচিত, নিদর্শনগুলিকে সংজ্ঞায়িত করে কাজ করে যা আপনি স্ট্রিংয়ের ভিতরে নির্দিষ্ট অক্ষর বা শব্দগুলি অনুসন্ধান করতে ব্যবহার করতে পারেন৷
একবার আপনি যে প্যাটার্নটি ব্যবহার করতে চান তা সংজ্ঞায়িত করলে, আপনি সম্পাদনা করতে পারেন, নির্দিষ্ট কিছু অক্ষর বা শব্দ মুছে ফেলতে পারেন, একটি জিনিসকে অন্যটির জন্য প্রতিস্থাপন করতে পারেন, একটি ফাইল বা সেই নির্দিষ্ট প্যাটার্ন রয়েছে এমন কোনো স্ট্রিং থেকে প্রাসঙ্গিক তথ্য বের করতে পারেন ইত্যাদি।
আপনি কেন রেজেক্স শিখবেন?
Regex আপনাকে এমনভাবে পাঠ্য প্রক্রিয়াকরণ করতে দেয় যা আপনার অনেক সময় বাঁচাতে পারে। এটি প্রক্রিয়ায় কিছু মজার পরিচয়ও দিতে পারে৷
regex ব্যবহার করে তথ্য সনাক্ত করা অনেক সহজ করতে পারে। একবার আপনি আপনার টার্গেট খুঁজে পেলে, আপনি ব্যাচ সম্পাদনা/রিপ্লেট/মুছে ফেলতে পারেন বা আপনার যা কিছু প্রসেসিং করতে হবে।
রেজেক্স ব্যবহারের কিছু বাস্তব উদাহরণ হল ব্যাচ ফাইলের নামকরণ, লগ পার্সিং, ফর্ম যাচাইকরণ, কোডবেসে ব্যাপক সম্পাদনা করা এবং পুনরাবৃত্ত অনুসন্ধান।
এই টিউটোরিয়ালে, আমরা এই সাইটের সাহায্যে রেজেক্স বেসিকগুলি কভার করতে যাচ্ছি। পরে, আমি কিছু রেজেক্স চ্যালেঞ্জ উপস্থাপন করব যা আপনি পাইথন ব্যবহার করে সমাধান করবেন। sed-এর মতো টুলগুলি কীভাবে ব্যবহার করবেন তাও আমি আপনাকে দেখাব এবং grep regex সহ।
জীবনের অনেক কিছুর মতো, নিয়মিত অভিব্যক্তি হল সেই জিনিসগুলির মধ্যে একটি যা আপনি শুধুমাত্র করার মাধ্যমেই বুঝতে পারবেন। আপনি এই নিবন্ধের মধ্য দিয়ে যাচ্ছেন বলে আমি আপনাকে রেজেক্সের সাথে খেলার জন্য উত্সাহিত করছি৷
সূচিপত্র
- রেজেক্স বেসিকস
- সঠিক মিল
- অক্ষর সেট
- রেজেক্সে রেঞ্জের সাথে মিল করুন
- সেটের মধ্যে নেই এমন যেকোনো অক্ষর মেলে
- চরিত্রের ক্লাস
- কোয়ান্টিফায়ার
- গ্রুপ ক্যাপচার করুন
- কিভাবে regex-এ লজিক্যাল OR ব্যবহার করবেন
- কীভাবে ক্যাপচার গ্রুপগুলিকে রেফারেন্স করবেন
- কিভাবে ক্যাপচার গ্রুপের নাম দিতে হয়
- কমান্ড লাইন টুলের সাথে কিভাবে regex ব্যবহার করবেন
- গ্রেপের সাথে পুনরাবৃত্ত রেজেক্স অনুসন্ধান
- sed দিয়ে প্রতিস্থাপন
- Advanced Regex:Lookarounds
- পেছনে তাকান
- লুকহেডস
- রেজেক্সের ব্যবহারিক উদাহরণ
- লগ পার্সিং
- বাল্ক ফাইলের নামকরণ
- ইমেল যাচাইকরণ
- পাসওয়ার্ড সীমাবদ্ধতা
- শেষ কথা
রেজেক্স বেসিক
একটি নিয়মিত অভিব্যক্তি একটি প্যাটার্নের সাথে মেলে এমন অক্ষরের একটি ক্রম ছাড়া আর কিছুই নয়। আক্ষরিক অক্ষর (যেমন 'abc') ব্যবহার করার পাশাপাশি, কিছু মেটা অক্ষর (*,+,? ইত্যাদি) রয়েছে যার বিশেষ উদ্দেশ্য রয়েছে। এছাড়াও ক্যারেক্টার ক্লাসের মত বৈশিষ্ট্য রয়েছে যা আপনাকে আপনার রেগুলার এক্সপ্রেশন সহজ করতে সাহায্য করতে পারে।
যেকোন রেজেক্স লেখার আগে, আপনি যে প্যাটার্নটি খুঁজছেন তার জন্য আপনাকে সমস্ত মৌলিক কেস এবং এজ কেস সম্পর্কে জানতে হবে।
উদাহরণস্বরূপ, আপনি যদি 'হ্যালো ওয়ার্ল্ড'-এর সাথে মিল রাখতে চান, আপনি কি চান যে লাইনটি 'হ্যালো' দিয়ে শুরু হোক নাকি এটি কিছু দিয়ে শুরু হতে পারে? আপনি কি 'হ্যালো' এবং 'ওয়ার্ল্ড' এর মধ্যে ঠিক একটি জায়গা চান নাকি আরও থাকতে পারে? অন্যান্য অক্ষর কি 'ওয়ার্ল্ড' এর পরে আসতে পারে বা লাইনটি সেখানে শেষ হওয়া উচিত? আপনি কেস সংবেদনশীলতা সম্পর্কে যত্নশীল? ইত্যাদি।
আপনার রেজেক্স লিখতে বসার আগে এই ধরনের প্রশ্নগুলির উত্তর আপনার অবশ্যই থাকতে হবে।
সঠিক মিল
রেজেক্সের সবচেয়ে মৌলিক ফর্মটিতে অক্ষরের একটি ক্রমকে একইভাবে মেলানো জড়িত যেভাবে আপনি একটি পাঠ্য সম্পাদকে Ctrl-F এর সাথে করতে পারেন।
উপরে আপনি মিলের সংখ্যা দেখতে পাবেন এবং নীচে রেজেক্স অক্ষর অনুসারে অক্ষরের সাথে কী মেলে তার জন্য একটি ব্যাখ্যা দেওয়া হয়েছে৷
অক্ষর সেট
রেজেক্স অক্ষর সেট আপনাকে অক্ষরগুলির একটি গ্রুপ থেকে যে কোনও একটি অক্ষর মেলানোর অনুমতি দেয়। দলটি বর্গাকার বন্ধনী দ্বারা বেষ্টিত []।
উদাহরণস্বরূপ, t[ah]i মেলে "তাই" এবং "থি"। এখানে 't' এবং 'i' স্থির আছে কিন্তু তাদের মধ্যে 'a' বা 'h' হতে পারে।
রেজেক্সে রেঞ্জের সাথে মিল করুন
কখনও কখনও আপনি অক্ষরগুলির একটি গোষ্ঠীর সাথে মেলাতে চাইতে পারেন যা প্রকৃতিতে ক্রমিক, যেমন কোন বড় হাতের ইংরেজি অক্ষর। কিন্তু সমস্ত 26টি অক্ষর লেখা বেশ ক্লান্তিকর হবে।
Regex রেঞ্জের সাথে এই সমস্যাটি সমাধান করে। "-" একটি পরিসীমা অপারেটর হিসাবে কাজ করে। কিছু বৈধ ব্যাপ্তি নীচে দেখানো হয়েছে:
রেঞ্জ ম্যাচ [A-Z]বড় হাতের অক্ষর[a-z]ছোট হাতের অক্ষর[0-9]যেকোনো সংখ্যা
আপনি আংশিক ব্যাপ্তিও নির্দিষ্ট করতে পারেন, যেমন [b-e] যেকোনো অক্ষর 'bcde' বা [3-6] এর সাথে মেলে '3456' সংখ্যার যে কোনো একটির সাথে মেলে।
আপনি একটি অক্ষর সেটের মধ্যে শুধুমাত্র একটি পরিসীমা নির্দিষ্ট করার মধ্যে সীমাবদ্ধ নন৷ আপনি একাধিক ব্যাপ্তি ব্যবহার করতে পারেন এবং অন্য কোন অতিরিক্ত অক্ষর(গুলি) এর সাথে তাদের একত্রিত করতে পারেন। এখানে, [3-6u-w;] '3456uvw' বা সেমিকোলন ';' এর যেকোনো একটির সাথে মিলবে।
সেটের মধ্যে নেই এমন যেকোনো অক্ষর মেলে
যদি আপনি একটি '^' দিয়ে সেটের উপসর্গ করেন, তাহলে বিপরীত অপারেশন করা হবে। উদাহরণস্বরূপ, [^A-Z0-9] বড় হাতের অক্ষর এবং সংখ্যা ছাড়া যেকোনো কিছুর সাথে মিলবে।
চরিত্রের ক্লাস
রেজেক্স লেখার সময়, আপনাকে নির্দিষ্ট গোষ্ঠীর সাথে মেলাতে হবে যেমন সংখ্যাগুলি প্রায়শই এবং একই অভিব্যক্তিতে একাধিকবার।
সুতরাং উদাহরণস্বরূপ, আপনি কীভাবে 'অক্ষর-ডিজিট-লেটার-ডিজিট' এর মতো একটি প্যাটার্নের সাথে মিল করবেন?
আপনি এখন পর্যন্ত যা শিখেছেন তা দিয়ে আপনি [a-zA-Z]-[0-9]-[a-zA-z]-[0-9] নিয়ে আসতে পারেন . এটি কাজ করে, কিন্তু প্যাটার্নের দৈর্ঘ্য বড় হওয়ার সাথে সাথে অভিব্যক্তিটি কীভাবে অগোছালো হয়ে উঠতে পারে তা আপনি দেখতে পাচ্ছেন৷
অভিব্যক্তিকে সহজ করার জন্য, অঙ্কের মতো সু-সংজ্ঞায়িত অক্ষর গোষ্ঠীতে ক্লাসগুলি বরাদ্দ করা হয়েছে। নিম্নলিখিত সারণী এই শ্রেণীগুলি এবং অক্ষর সেট সহ তাদের সমতুল্য অভিব্যক্তি দেখায়:
ClassMatches সমতুল্য অভিব্যক্তি .নতুন লাইন ছাড়া অন্য কিছুঅক্ষর ক্লাসগুলি বেশ সহজ এবং আপনার অভিব্যক্তিগুলিকে আরও পরিষ্কার করে তোলে। আমরা এই টিউটোরিয়াল জুড়ে ব্যাপকভাবে সেগুলি ব্যবহার করব, যাতে আপনি এই টেবিলটিকে একটি রেফারেন্স পয়েন্ট হিসাবে ব্যবহার করতে পারেন এবং আপনি যদি কোনও ক্লাস ভুলে যান তবে এখানে ফিরে আসতে পারেন৷
বেশিরভাগ সময়, আমরা একটি প্যাটার্নের সমস্ত অবস্থানের বিষয়ে চিন্তা করব না। "।" ক্লাস আমাদের একটি সেটে সম্ভাব্য সমস্ত অক্ষর লেখা থেকে বাঁচায়।
উদাহরণস্বরূপ, t.. t দিয়ে শুরু হওয়া যেকোনো কিছুর সাথে মেলে এবং এর পরে যেকোনো দুটি অক্ষর। এটি আপনাকে SQL LIKE মনে করিয়ে দিতে পারে অপারেটর যা t%% ব্যবহার করবে একই জিনিস সম্পাদন করতে।
কোয়ান্টিফায়ার
"প্যাটার্ন" এবং "পুনরাবৃত্তি" শব্দটি একসাথে চলে। আপনি যদি একটি 3 সংখ্যার সংখ্যার সাথে মিলতে চান তাহলে আপনি \d\d\d ব্যবহার করতে পারেন . কিন্তু যদি আপনার 11টি সংখ্যা মেলাতে হয়? আপনি 11 বার '\d' লিখতে পারেন, কিন্তু regex লেখার সময় বা যেকোন ধরনের প্রোগ্রামিং করার সময় একটি সাধারণ নিয়ম হল যে আপনি যদি নিজেকে দুইবারের বেশি পুনরাবৃত্তি করতে দেখেন তবে আপনি সম্ভবত কিছু বৈশিষ্ট্য সম্পর্কে অজ্ঞ।
রেজেক্সে, আপনি এই উদ্দেশ্যে কোয়ান্টিফায়ার ব্যবহার করতে পারেন। 11টি সংখ্যা মেলানোর জন্য, আপনি কেবল \d{11} অভিব্যক্তি লিখতে পারেন .
নীচের সারণীতে আপনি রেজেক্সে ব্যবহার করতে পারেন এমন কোয়ান্টিফায়ারগুলি তালিকাভুক্ত করে:
কোয়ান্টিফায়ার ম্যাচগুলি *0 বা তার বেশি?0 বা 1+1 বা তার বেশি{n}ঠিক n বার{n, }n বা আরও বার{n, m}n থেকে m বার অন্তর্ভুক্ত
এই উদাহরণে, অভিব্যক্তি can\s+write can মেলে 1 বা তার বেশি হোয়াইটস্পেস অনুসরণ করে write . কিন্তু আপনি দেখতে পাচ্ছেন 'ক্যানরাইট' \s+ হিসাবে মিলছে না মানে অন্তত একটি হোয়াইটস্পেস মিলে যাওয়া প্রয়োজন। এটি উপযোগী যখন আপনি পাঠ্যের মাধ্যমে অনুসন্ধান করছেন যা ছাঁটা নয়৷
আপনি কি অনুমান করতে পারেন can\s?write মিলবে?
গ্রুপ ক্যাপচার করুন
ক্যাপচার গ্রুপগুলি হল সাব-এক্সপ্রেশনগুলি বন্ধনী () এ আবদ্ধ। আপনার যেকোনো সংখ্যক ক্যাপচার গ্রুপ থাকতে পারে, এমনকি নেস্টেড ক্যাপচার গ্রুপও থাকতে পারে।
অভিব্যক্তি (The ){2} 'দ্য' দুইবার মেলে। কিন্তু একটি ক্যাপচার গ্রুপ ছাড়া, অভিব্যক্তি The {2} 'The'-এর সাথে 2টি স্পেস মেলে, কারণ কোয়ান্টিফায়ারটি স্পেস ক্যারেক্টারে প্রয়োগ করা হবে এবং গ্রুপ হিসেবে 'The'-এ নয়।
আপনি ক্যাপচার গ্রুপের ভিতরে যেকোন প্যাটার্নের সাথে মেলাতে পারেন যেমন আপনি যেকোনো বৈধ রেজেক্সের সাথে করবেন। এখানে (is\s+){2} মেলে যদি এটি 'is' এর পরে 1 বা তার বেশি স্পেস দুইবার দ্বারা অনুসরণ করে।
কিভাবে লজিক্যাল বা রেজেক্সে ব্যবহার করবেন
আপনি "|" ব্যবহার করতে পারেন একাধিক নিদর্শন মেলে. This is (good|bad|sweet) ম্যাচ 'এটি' এর পরে 'ভাল' বা 'খারাপ' বা 'মিষ্টি'।
আবার, আপনি এখানে ক্যাপচার গ্রুপ গুরুত্ব বুঝতে হবে. This is good|bad|sweet অভিব্যক্তিটি কী তা নিয়ে ভাবুন মিলবে?
একটি ক্যাপচার গ্রুপের সাথে, good|bad|sweet This is থেকে বিচ্ছিন্ন . কিন্তু যদি এটি একটি ক্যাপচার গ্রুপের মধ্যে না থাকে, তবে পুরো রেজেক্স শুধুমাত্র একটি গ্রুপ। তাই অভিব্যক্তি This is good|bad|sweet স্ট্রিংটিতে 'এটি ভালো' বা 'খারাপ' বা 'মিষ্টি' থাকলে মিলবে।
কিভাবে ক্যাপচার গ্রুপগুলিকে রেফারেন্স করবেন
ক্যাপচার গ্রুপগুলি একই অভিব্যক্তিতে বা প্রতিস্থাপন করার সময় উল্লেখ করা যেতে পারে যেমন আপনি প্রতিস্থাপন ট্যাবে দেখতে পাচ্ছেন।
বেশিরভাগ টুল এবং ভাষা আপনাকে '\n' দিয়ে nম ক্যাপচার করা গ্রুপকে উল্লেখ করতে দেয়। এই সাইটে '$n' ব্যবহার করা হয় প্রতিস্থাপনের ক্ষেত্রে উল্লেখ করার সময়। আপনি যে টুল বা ভাষা ব্যবহার করছেন তার উপর নির্ভর করে প্রতিস্থাপনের জন্য সিনট্যাক্স পরিবর্তিত হবে। জাভাস্ক্রিপ্টের জন্য, উদাহরণস্বরূপ, এটি '$n', যখন পাইথনের জন্য এটি '\n'।
অভিব্যক্তিতে (This) is \1 power , 'এটি' ক্যাপচার করা হয় এবং তারপর '\1' এর সাথে উল্লেখ করা হয়, কার্যকরভাবে This is This power মেলে .
কীভাবে ক্যাপচার গ্রুপের নাম রাখবেন
আপনি সিনট্যাক্স (?<name>pattern) দিয়ে আপনার ক্যাপচার গ্রুপের নাম দিতে পারেন এবং \k<name> এর সাথে একই অভিব্যক্তিতে তাদের ব্যাকরেফারেন্স করুন .
প্রতিস্থাপনের ক্ষেত্রে, $<name> দ্বারা রেফারেন্স করা হয় . এটি জাভাস্ক্রিপ্টের সিনট্যাক্স এবং ভাষাগুলির মধ্যে পরিবর্তিত হতে পারে। আপনি এখানে পার্থক্য সম্পর্কে জানতে পারেন. এছাড়াও মনে রাখবেন যে এই বৈশিষ্ট্যটি কিছু ভাষায় উপলব্ধ নাও হতে পারে৷
(?<lang>[\w+]+) is the best but \k<lang> .* অভিব্যক্তিতে , প্যাটার্ন [\w+]+ 'lang' নামের সাথে ক্যাপচার করা হয় এবং \k<lang> দিয়ে রেফারেন্স করা হয় . এই প্যাটার্নটি যেকোনো শব্দের অক্ষর বা '+' অক্ষর 1 বা তার বেশি বার মেলে। .* রেজেক্সের শেষে যে কোনো অক্ষর 0 বা তার বেশি বার মেলে। এবং পরিশেষে প্রতিস্থাপনে, রেফারেন্সিং $<lang> দ্বারা সম্পন্ন হয় .
ভাল CLI টুল উপলব্ধ রয়েছে যা আপনাকে আপনার টার্মিনাল থেকে রেজেক্স করতে দেয়। এই সরঞ্জামগুলি আপনার আরও বেশি সময় বাঁচায় কারণ আপনি কিছু ভাষায় কোড না লিখে এবং তারপরে কম্পাইল বা ব্যাখ্যা না করে সহজেই বিভিন্ন রেজেক্স পরীক্ষা করতে পারেন।
কিছু সুপরিচিত টুল হল grep, sed, এবং awk। আপনি কিভাবে এই টুলগুলি ব্যবহার করতে পারেন সে সম্পর্কে কিছু ধারণা দেওয়ার জন্য আসুন কয়েকটি উদাহরণ দেখি৷
গ্রেপের সাথে পুনরাবৃত্ত রেজেক্স অনুসন্ধান
আপনি grep এর মাধ্যমে regex এর ক্ষমতা চালাতে পারেন। গ্রেপ একটি ফাইলে প্যাটার্ন অনুসন্ধান করতে পারে বা পুনরাবৃত্তিমূলক অনুসন্ধান করতে পারে।
আপনি যদি উইন্ডোজে থাকেন তবে আপনি উইনজেট ব্যবহার করে গ্রেপ ইনস্টল করতে পারেন। পাওয়ারশেলে এই কমান্ডটি চালান:
winget install -e --id GnuWin32.Grep
আমি আমার বিশ্ববিদ্যালয়ে একটি CTF প্রতিযোগিতার জন্য তৈরি করা একটি চ্যালেঞ্জের সমাধান দেখাব।
চ্যালেঞ্জের সাথে সংযুক্ত ফাইলটি একটি জিপ ফাইল যাতে একাধিক স্তরের ডিরেক্টরি এবং এতে অনেকগুলি ফাইল রয়েছে। প্রতিযোগিতার নাম ছিল পতাকা বিন্যাস coderush{flag is here} সহ Coderush . তাই আপনাকে coderush{.*} প্যাটার্ন অনুসন্ধান করতে হবে যা পতাকা বিন্যাসের সাথে মিলবে coderush{any character here} .
unzip ripG.zip দিয়ে ফাইলটি আনজিপ করুন এবং cd ripG এর সাথে সিডি করুন .
358টি ডিরেক্টরি এবং 8731টি ফাইল রয়েছে। ফাইলে একের পর এক প্যাটার্ন অনুসন্ধান করার পরিবর্তে, আপনি এইভাবে grep নিয়োগ করতে পারেন:
grep --color -R "coderush{.*}"
"-R" পতাকা পুনরাবৃত্ত অনুসন্ধান সক্ষম করে৷
আপনি এখানে grep এবং এর কমান্ড লাইন বিকল্প সম্পর্কে আরও জানতে পারেন
sed দিয়ে প্রতিস্থাপন
আপনি একটি রেজেক্স উল্লেখ করে পাঠ্য ফাইলগুলিতে সন্নিবেশ, মুছে ফেলা, প্রতিস্থাপন করতে sed ব্যবহার করতে পারেন। আপনি যদি উইন্ডোতে থাকেন, আপনি এখান থেকে sed পেতে পারেন। অথবা আপনি যদি WSL ব্যবহার করেন, grep এবং sed এর মতো টুল ইতিমধ্যেই পাওয়া যাবে।
এটি sed এর সবচেয়ে সাধারণ ব্যবহার:
sed 's/pattern/replacement/g' filename
echo "${text}" | sed 's/pattern/replacement/g'
এখানে, সমস্ত ঘটনা প্রতিস্থাপন করার জন্য "g" বিকল্পটি নির্দিষ্ট করা হয়েছে।
কিছু অন্যান্য দরকারী বিকল্প হল -n সমস্ত লাইন প্রিন্ট করার ডিফল্ট আচরণ দমন করতে এবং শুধুমাত্র রেজেক্স দ্বারা প্রভাবিত লাইনগুলি মুদ্রণ করতে g এর পরিবর্তে p ব্যবহার করে৷
আসুন texts.txt এর বিষয়বস্তু দেখে নেওয়া যাক।
Hello rand chars World 56 rand chars
Henlo 52 rand chars W0rld rand chars
GREP rand chars Henlo 62 rand chars
Henlo 10 rand chars Henlo rand chars
GREP rand chars Henlo 45 rand chars
আমাদের কাজ হল Henlo number প্রতিস্থাপন করা Hello number সহ শুধুমাত্র লাইনে যেখানে "GREP" উপস্থিত থাকে। সুতরাং, আমরা Henlo ([0-9]+) প্যাটার্নটি অনুসন্ধান করছি যেটি 'হেনলো' এর সাথে মিলবে তার পরে 1 বা তার বেশি সংখ্যা এবং সমস্ত সংখ্যা ক্যাপচার করা হয়েছে। তারপর আমাদের প্রতিস্থাপন স্ট্রিং হবে Hello \1 - '\1' অঙ্কগুলি ধারণকারী ক্যাপচার গ্রুপকে উল্লেখ করছে।
এটি সম্পন্ন করার একটি উপায় হল "GREP" উপস্থিত লাইনগুলিকে grep করতে grep ব্যবহার করে তারপর sed দিয়ে প্রতিস্থাপন করুন৷
grep "GREP" texts.txt | sed -En 's/Henlo ([0-9]+)/Hello \1/p'
"-E" বিকল্পটি বর্ধিত রেজেক্স সক্ষম করে যা ছাড়া আপনাকে বন্ধনী থেকে এড়িয়ে যেতে হবে।
অথবা আপনি শুধু sed ব্যবহার করতে পারেন. /pattern/ ব্যবহার করুন প্রতিস্থাপনকে শুধুমাত্র সেই লাইনগুলিতে সীমাবদ্ধ করতে যেখানে প্যাটার্ন উপস্থিত রয়েছে।
sed -En '/GREP/ s/Henlo ([0-9]+)/Hello \1/p' texts.txt
উন্নত রেজেক্স:লুকঅ্যারাউন্ডস
লুকহেডস এবং লুকবিহাইন্ডস (একত্রে লুকঅ্যারাউন্ডস নামে পরিচিত) হল রেজেক্সের বৈশিষ্ট্য যা আপনাকে ম্যাচটিতে অন্তর্ভুক্ত না করেই প্যাটার্নের অস্তিত্ব পরীক্ষা করতে দেয়।
আপনি এগুলিকে শূন্য প্রস্থের দাবি হিসাবে ভাবতে পারেন - এগুলি একটি প্যাটার্নের অস্তিত্বের দাবি করে তবে ম্যাচের কোনও অক্ষর ব্যবহার করে না। এগুলি খুব শক্তিশালী বৈশিষ্ট্য, তবে এগুলি গণনাগতভাবে ব্যয়বহুলও। সুতরাং আপনি যদি প্রায়শই এগুলি ব্যবহার করেন তবে আপনি কর্মক্ষমতার উপর নজর রাখবেন তা নিশ্চিত করুন৷
পেছনে তাকান
ধরা যাক আপনি 'লিনাক্স' শব্দের সাথে মিল রাখতে চান, কিন্তু আপনার 2টি শর্ত আছে।
- লিনাক্স হওয়ার আগে 'GNU' শব্দটি অবশ্যই আসবে। যদি কোনো লাইনে 'linux' থাকে কিন্তু এর আগে 'GNU' না থাকে, আমরা সেই লাইনটি বাতিল করতে চাই।
- আমরা শুধুমাত্র
linuxএর সাথে মিল রাখতে চাই এবং অন্য কিছু না।
আমরা ইতিমধ্যেই জানি কিভাবে ১ম শর্ত পূরণ করতে হয়। GNU.* 'GNU' এর সাথে যেকোন সংখ্যক অক্ষরের সাথে মিলবে। তারপর অবশেষে আমরা linux শব্দটি মেলে . এটি সমস্ত GNU-any-characters-linux এর সাথে মিলবে৷ .
কিন্তু কিভাবে আমরা GNU.* মেলানো আটকাতে পারি এখনও প্রথম শর্ত বজায় রাখার সময়?
সেখানেই একটি ইতিবাচক লুক বিহাইন্ড আসে৷ আপনি একটি ক্যাপচার গ্রুপকে ?<= দিয়ে প্রিফিক্স করে ইতিবাচক লুক বিহাইন্ড হিসাবে চিহ্নিত করতে পারেন৷ . এই উদাহরণে, অভিব্যক্তিটি (?<=GNU.*)linux হয়ে যায় .
এখন শুধুমাত্র linux মিলে যায় এবং অন্য কিছু না।
মনে রাখবেন যে এক্সপ্রেশনগুলি (?<=GNU.*)linux এবং linux(?<=GNU.*) ঠিক একই আচরণ করবে। ২য় অভিব্যক্তিতে, যদিও linux পিছনের দিকে তাকানোর আগে আছে, .* আছে 'GNU' এর পরে যা linux এর সাথে মেলে . এর মানে এটি পিছনের চেহারাকে সন্তুষ্ট করে।
এটিকে সহজ করতে, পিছনে না তাকিয়ে প্যাটার্ন সম্পর্কে চিন্তা করুন। প্যাটার্ন GNU.* আমাদের ক্ষেত্রে linux মেলে 'GNU' এবং এর পরে যেকোন কিছুর সাথে মিলিত হবে .
এখন আমরা (?<=C)X অভিব্যক্তিটি একটি সাধারণীকৃত বিবৃতি পেতে পারি প্যাটার্ন X-এর সাথে মিলবে - শুধুমাত্র যদি প্যাটার্ন C X এর আগে আসে (এবং C অবশ্যই ম্যাচটিতে অন্তর্ভুক্ত করা উচিত নয়)।
আপনি ১ম শর্তটিও বিপরীত করতে পারেন। linux শব্দটি রয়েছে এমন লাইনগুলিকে মেলুন শুধুমাত্র GNU হলে এর আগে কখনও আসেনি। একে নেতিবাচক দৃষ্টিভঙ্গি বলা হয়। এই ক্ষেত্রে উপসর্গ হল ?<! . পূর্ববর্তী রাশিটির বিপরীতটি হবে (?<!GNU.*)linux .
লুকহেডস
লুকহেডগুলিও লুক বিহাইন্ডসের মতো দাবী, যেমন আপনি আগের উদাহরণে দেখেছেন। পার্থক্য শুধু এই যে, পিছনের দিকে তাকিয়ে থাকা আগে দাবি করে এবং সামনের দিকে তাকানোর পরে।
ধরা যাক আপনার এই দুটি শর্ত আছে:
- মিলান
Helloশুধুমাত্রWorldহলে এর পরে কোথাও আসে। - শুধু হ্যালো মেলে অন্য কিছু নয়।
পজিটিভ লুকআহেডের উপসর্গ হল ?= . অভিব্যক্তি Hello(?=.*World) উভয় শর্ত পূরণ করবে। এটি Hello.*World এর মত শুধুমাত্র Hello ছাড়া মিলবে যেখানে Hello.*World 'হ্যালো', 'ওয়ার্ল্ড' এবং এর মধ্যে যেকোনো কিছুর সাথে মিলবে।
ইতিবাচক চেহারার পিছনের উদাহরণের মতো, অভিব্যক্তিগুলি Hello(?=.*World)৷ এবং (?=.*World)Hello সমতুল্য কারণ .* 'World' এর সাথে Hello মেলে , ১ম শর্ত সন্তুষ্ট।
নেতিবাচক দৃষ্টিভঙ্গি হল পিছনের নেতিবাচক চেহারার পরিপূরক। আপনি এটিকে ?! দিয়ে উপসর্গ দিয়ে ব্যবহার করতে পারেন . (?!World)Hello মিলবে Hello শুধুমাত্র যদি কোন World না থাকে এর পরে যে কোন জায়গায়।
এখানে সিনট্যাক্সের একটি সংক্ষিপ্ত বিবরণ রয়েছে যখন আপনি প্যাটার্ন X-কে দাবী C-এর সাথে মেলাতে চান।
OperationRegEx ইতিবাচক দৃষ্টিভঙ্গি(?=C)X নেতিবাচক দৃষ্টিভঙ্গি(?!C)X পজিটিভ লুক বিহাইন্ড(?<=C)X নেতিবাচক চেহারা(?<!C)X লগ পার্সিং
এই লগ ফাইলে, এই লাইনগুলি যা আমরা যত্ন করি:
[1/10000] Train loss: 11.30368, Valid loss: 8.95446, Elapsed_time: 7.58941
[500/10000] Train loss: 0.96180, Valid loss: 0.20098, Elapsed_time: 82.48651
[1000/10000] Train loss: 0.04051, Valid loss: 0.11927, Elapsed_time: 156.86243
আমাদের কাজ হল প্রশিক্ষনের ক্ষয়ক্ষতি এবং বৈধতার ক্ষতি বের করা যেমন যুগের উপর ক্ষতির পরিকল্পনা করা। আমাদের 11.30368, 0.96180, 0.04051 এর মত প্রশিক্ষণের ক্ষতির মান বের করতে হবে এবং তাদের একটি অ্যারের মধ্যে রাখুন।
সমস্ত প্রাসঙ্গিক মান 'Train loss: দিয়ে উপসর্গযুক্ত ', তাই আমরা এটিকে আমাদের রেজেক্সে ব্যবহার করতে পারি। ফ্লোট সংখ্যার সাথে মেলাতে আমাদের কিছু সংখ্যার সাথে একটি ". মিলতে হবে " এবং তারপরে আরও সংখ্যা দ্বারা অনুসরণ করা হয়। আপনি \d+\.\d+ দিয়ে এটি করতে পারেন . কারণ আমরা এই সংখ্যাগুলির ট্র্যাক রাখতে চাই, সেগুলি একটি ক্যাপচার গ্রুপের মধ্যে থাকা উচিত৷
হিসাবে "।" রেজেক্সে বিশেষ উদ্দেশ্য আছে, যখন আপনি একটি "।" অক্ষর আপনাকে ব্যাকস্ল্যাশ দিয়ে এড়িয়ে যেতে হবে। এটি একটি বিশেষ উদ্দেশ্য সহ সমস্ত অক্ষরের জন্য প্রযোজ্য। তবে আপনাকে এটি একটি অক্ষর সেটের মধ্যে এড়িয়ে যেতে হবে না।
এটিকে একত্রে রেখে, প্রশিক্ষণের ক্ষতি নিষ্কাশনের অভিব্যক্তি হল Train loss: (\d+\.\d+) . আমরা Valid loss: (\d+\.\d+) এর মাধ্যমে বৈধতা ক্ষতি নিষ্কাশন করতে একই যুক্তি ব্যবহার করতে পারি .
পাইথন ব্যবহার করে এই তথ্য বের করার একটি উপায় এখানে রয়েছে:
import re
f = open("log_train.txt", "r").read()
train_loss = re.findall(r'Train loss: (\d+\.\d+)', f)
valid_loss = re.findall(r'Valid loss: (\d+\.\d+)', f)
train_loss = [float(i) for i in train_loss]
valid_loss = [float(i) for i in valid_loss]
print("train_loss =", train_loss)
print("")
print("valid_loss =", valid_loss)
যখন একটি ক্যাপচার গ্রুপ থাকে, re.findall সমস্ত লাইন অনুসন্ধান করে এবং একটি তালিকায় ক্যাপচার গ্রুপের ভিতরে মানগুলি প্রদান করে।
যেকোনো রেজেক্স ফাংশন শুধুমাত্র স্ট্রিং ফেরত দেয়, তাই মানগুলি ফ্লোটে রূপান্তরিত হয় এবং মুদ্রিত হয়। তারপর আপনি সরাসরি অন্য পাইথন স্ক্রিপ্টে ফ্লোটের তালিকা হিসাবে ব্যবহার করতে পারেন।
এটি হল ফলাফল:
আপনি sed ব্যবহার করতে পারেন, train_losses.txt-এ আউটপুট সংরক্ষণ করতে পারেন এবং ফাইল থেকে পড়তে পারেন। প্রথমে আমরা '/Train/' ব্যবহার করি শুধুমাত্র 'Train' উপস্থিত লাইনগুলোকে টার্গেট করতে তারপর আমরা আগের মতো একই রেজেক্স প্রয়োগ করছি।
sed -En '/Train/ s/.*Train loss: ([0-9]+\.[0-9]+).*/\1/p' log_train.txt | tee train_losses.txt
".*" শুরুতে এবং শেষে যোগ করা হয় যাতে sed সমস্ত প্রাসঙ্গিক লাইনের বিষয়বস্তুর সাথে মেলে। তারপর পুরো লাইনটি ক্যাপচার গ্রুপের মান দ্বারা প্রতিস্থাপিত হয়। tee কমান্ডটি sed-এর আউটপুটকে train_losses.txt-এ পুনঃনির্দেশিত করতে ব্যবহৃত হয় যখন টার্মিনালে বিষয়বস্তু মুদ্রণ করা হয়।
যুগগুলি বের করার জন্য আপনার কী দরকার তা নিয়ে ভাবতে একটু সময় নিন। এই ধরনের সমস্ত লাইনের জন্য আপনাকে [500/10000] থেকে 500 বের করতে হবে। অ্যারেটি [1, 500, 1000, 1500, ...] এর মতো হওয়া উচিত। আপনি একই পদ্ধতি অনুসরণ করতে পারেন যা আমরা আগের উদাহরণের জন্য ব্যবহার করেছি।
মনে রাখবেন আপনি যদি "[ এর সাথে মিল রাখতে চান " অথবা "] ", আপনাকে এটি থেকে পালাতে হবে। উত্তর এখানে দেওয়া হল।
বাল্ক ফাইলের নামকরণ
আপনার কাছে কিছু র্যান্ডম মান সহ এই ফাইলগুলি উপসর্গ হিসাবে রয়েছে। আপনাকে সমস্ত ফাইলের নাম 1.mp4, 2.mp4 ইত্যাদি হিসাবে পুনঃনামকরণ করতে হবে৷ এইভাবে ফাইলগুলি তৈরি হয়েছিল৷
এটি একটি সাধারণ দৃশ্য যেখানে আপনার কাছে ফাইলগুলির একটি তালিকা রয়েছে যার নামটিতে তাদের ক্রম নম্বর রয়েছে তবে আরও কিছু অক্ষর রয়েছে যা আপনি চান না৷
প্যাটার্নটি পর্ব পর্যন্ত যেকোনো কিছুর সাথে মিলতে হবে তারপর একটি আন্ডারস্কোর এবং তারপর সংখ্যা এবং শেষে .mp4।
প্রাসঙ্গিক মান হল '.mp4' এর আগের সংখ্যা যা আমরা একটি ক্যাপচার গ্রুপের ভিতরে রাখব। .*Episode_ সংখ্যা পর্যন্ত সবকিছু মিলে যাবে। তারপর আমরা ([0-9]+) দিয়ে নম্বরটি ক্যাপচার করতে পারি এবং \.mp4 এর সাথে .mp4 মেলে .
তাই চূড়ান্ত রেজেক্স হল .*Episode_([0-9]+)\.mp4 . যেমন আমরা .mp4 রাখতে চাই প্রতিস্থাপন স্ট্রিং হবে \1.mp4 .
এটি sed ব্যবহার করে এটি সমাধান করার একটি উপায়।
for i in *.mp4; do
newname=$(echo $i | sed -En 's/.*Episode_([0-9]+)\.mp4/\1.mp4/p')
mv $i $newname
done;ls
প্রথমে নতুন নামটি একটি ভেরিয়েবলে সংরক্ষিত হয় এবং তারপর ফাইলটির নাম পরিবর্তন করতে mv কমান্ড ব্যবহার করা হয়।
আমরা কি শুধু .* ব্যবহার করতে পারতাম .*Episode_ এর জায়গায় ? এই উদাহরণে, হ্যাঁ. কিন্তু ফাইলের নাম থাকতে পারে যেমন Steins_Gate0.mp4 যেখানে 0 এটি চলচ্চিত্রের নামের অংশ এবং আপনি সত্যিই এই ফাইলটির নাম পরিবর্তন করতে চাননি তাই যতটা সম্ভব নির্দিষ্ট হওয়া সর্বদা ভাল৷
যদি কিছু ফাইলকে "Random_Episode6.mp4" নামে নাম দেওয়া হয়? পার্থক্য হচ্ছে, পর্বের পরে কোনো আন্ডারস্কোর নেই। আপনি কি পরিবর্তন করতে হবে?
উত্তর হল যে আপনাকে একটি যোগ করতে হবে "?" এটি ঐচ্ছিক করতে "_" এর পরে। regex হবে .*Episode_?([0-9]+)\.mp4 .
ইমেল যাচাইকরণ
ইমেল যাচাই করার জন্য সমস্ত ধরণের জটিল রেজেক্স রয়েছে৷
৷
এখানে একটি সহজ হল:^[^@ ]+@[^@.]+\.\w+$ . এটি A@B.C ফর্ম্যাটের সাথে মেলে
নীচের সারণীটি এই প্যাটার্নটিকে ছোট ছোট টুকরোগুলিতে বিভক্ত করে:
প্যাটার্ন ম্যাচগুলি^ লাইনের শুরু[^@ ]+ "@" এবং স্পেস অক্ষর@[^@.]+ ছাড়া অন্য কিছু @ এর পরে "@" এবং "" ছাড়া অন্য কিছু দ্বারা অনুসরণ করা হয়। অক্ষর\.\w+ "" তারপরে শব্দ অক্ষর$ লাইনের শেষ
regexr সাইটে, আপনি উপরের ডানদিকের কোণায় ফ্ল্যাগ ট্যাব থেকে মাল্টলাইন পতাকা সক্রিয় করতে পারেন। শেষে 'gm' নির্দেশ করে যে মাল্টিলাইন পতাকা সক্রিয় করা হয়েছে।
আমরা দেখতে পাচ্ছি যে লাইন 2,3,5,6 মিলছে না। আপনি কি কারণ খুঁজে পেতে পারেন এবং regex এর কোন অংশ এটিকে অযোগ্য করার জন্য দায়ী?
উত্তর এখানে দেওয়া হল
পাসওয়ার্ড সীমাবদ্ধতা
আপনি সীমাবদ্ধতা আরোপ করতে regex ব্যবহার করতে পারেন। এখানে আমরা ইতিবাচক দৃষ্টিভঙ্গির শক্তি উন্মোচন করব।
ধরা যাক আমরা একটি স্ট্রিং গ্রহণ করতে চাই শুধুমাত্র যদি এটিতে একটি সংখ্যা থাকে। আপনি ইতিমধ্যেই জানেন কিভাবে '\d' ক্লাস দিয়ে একটি সংখ্যা খুঁজে বের করতে হয়। এটি সম্পন্ন করতে, আমরা [^\d]*\d ব্যবহার করতে পারি . এটি যেকোনো অ-অঙ্কের অক্ষর 0 বা তার বেশি বার মেলে এবং তারপর একটি অঙ্কের সাথে মিলবে।
আমরা .*\d এক্সপ্রেশনটিও ব্যবহার করতে পারি এক অঙ্ক মেলে সুতরাং যদি স্ট্রিংটিতে কোন সংখ্যা না থাকে তাহলে লুকহেড ব্যর্থ হবে এবং সেই স্ট্রিংটির কোনো অক্ষরই মিলবে না, একটি খালি স্ট্রিং "" ফেরত দেবে।
যখন আমরা একটি প্রোগ্রামিং ভাষা ব্যবহার করি, তখন আমরা পরীক্ষা করতে পারি যে regex একটি খালি স্ট্রিং ফিরিয়ে দিয়েছে এবং নির্ধারণ করতে পারি যে সীমাবদ্ধতাগুলি সন্তুষ্ট নয়৷
আমরা একটি রেজেক্স তৈরি করব যা নিম্নলিখিত মানদণ্ডগুলি আরোপ করে:
- সর্বনিম্ন ৮ অক্ষর এবং সর্বোচ্চ ১৬ অক্ষর।
- অন্তত একটি ছোট হাতের অক্ষর।
- অন্তত একটি বড় হাতের অক্ষর।
- অন্তত একটি সংখ্যা।
এটি অর্জন করতে, আপনি ইতিবাচক দৃষ্টিভঙ্গি ব্যবহার করতে পারেন। এটি হল রেজেক্স:
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,16}$
নীচের সারণীটি ব্যাখ্যা করে যে রেজেক্সের কোন অংশ কোন সীমাবদ্ধতা আরোপ করে:
প্যাটার্ন আরোপিত সীমাবদ্ধতা.{8,16} সর্বনিম্ন ৮ এবং সর্বোচ্চ ১৬টি অক্ষর(?=.*[a-z]) ন্যূনতম একটি ছোট হাতের অক্ষর(?=.*[A-Z]) ন্যূনতম একটি বড় হাতের অক্ষর(?=.*\d) ন্যূনতম এক অঙ্ক
কমপক্ষে 5টি বড় হাতের অক্ষর চাপানোর জন্য আপনার কী পরিবর্তন দরকার?
আপনি ভাবতে পারেন (?=.*[A-Z]{5,}) কাজটি করবে। কিন্তু এই অভিব্যক্তির জন্য 5টি অক্ষর একসাথে থাকা প্রয়োজন। rand-ABCDE-rand এর মত একটি স্ট্রিং মিলবে কিন্তু 0AxBCDxE0 5টি বড় হাতের অক্ষর থাকা সত্ত্বেও মিলবে না (যেহেতু তারা সংলগ্ন নয়)।
আবারও, আমরা উদ্ধারকারী দলগুলোকে ধরে নিয়েছি। আমরা স্ট্রিং এর যে কোন জায়গায় 5টি বড় হাতের অক্ষর মেলাতে চাই। আমরা ইতিমধ্যেই জানি যে আমরা 1টি বড় হাতের অক্ষর .*[A-Z] এর সাথে মেলাতে পারি . এখন আমরা তাদের একটি ক্যাপচার গ্রুপের মধ্যে রাখব এবং ন্যূনতম 5 এর একটি কোয়ান্টিফায়ার সংযুক্ত করব। অভিব্যক্তিটি হবে (.*[A-Z]){5,} .
এখানে চূড়ান্ত উত্তর:
(?=.*[A-Z]) এর জায়গায় আপনার প্রয়োজন হবে (?=(.*[A-Z]){5,}) . অভিব্যক্তিটি ^(?=.*[a-z])(?=(.*[A-Z]){5,})(?=.*\d).{8,16}$ হয়ে যায় .
আরও শক্তিশালী পাসওয়ার্ড প্রয়োগ করতে আপনার পাসওয়ার্ডে নির্দিষ্ট শব্দ না থাকা প্রয়োজন হতে পারে।
উদাহরণস্বরূপ, pass থাকলে আমরা পাসওয়ার্ডটি প্রত্যাখ্যান করতে চাই অথবা 1234 . নেতিবাচক দৃষ্টিভঙ্গি এই কাজের জন্য হাতিয়ার। regex হবে ^(?!.*(pass|1234)).*$ .
এই রেজেক্সে, আমরা pass রাখি এবং 1234 একটি ক্যাপচার গ্রুপের ভিতরে এবং লজিক্যাল বা অপারেটর ব্যবহার করে। এই ক্যাপচার গ্রুপটি অন্য ক্যাপচার গ্রুপের ভিতরে নেস্টেড আছে যা ?!.* এর সাথে প্রিফিক্স করা হয়েছে . এটি একটি নেতিবাচক দৃষ্টিভঙ্গি তৈরি করে যা .{8,} দ্বারা কমপক্ষে 8টি অক্ষর থাকলে মেলে শর্ত সহ যে, pass অথবা 1234 স্ট্রিং এর কোথাও উপস্থিত হতে পারে না।
চূড়ান্ত শব্দ
আমি আশা করি আপনি এই নিবন্ধটি চলাকালীন একটি ভাল পরিমাণ অনুশীলন পেয়েছেন। আপনি কিছু সিনট্যাক্স ভুলে গেলে ঠিক আছে। মূল ধারণাগুলি বোঝা এবং রেজেক্সের সাথে কী সম্ভব তা সম্পর্কে ভাল ধারণা থাকা গুরুত্বপূর্ণ। তারপর, যদি আপনি একটি প্যাটার্ন ভুলে যান, আপনি শুধু এটি গুগল করতে পারেন বা একটি চিটশিট উল্লেখ করতে পারেন।
আপনি যত বেশি অনুশীলন করবেন, বাইরের সাহায্য ছাড়াই আপনি তত বেশি পাবেন। অবশেষে আপনি অত্যন্ত জটিল এবং কার্যকর রেজেক্স সম্পূর্ণ অফলাইনে লিখতে সক্ষম হবেন।
সেখানে ইতিমধ্যেই কিছু ভাল রেজেক্স চিটশিট রয়েছে, তাই আমি এখানে আরও গভীরভাবে কিছু তৈরি করতে চেয়েছিলাম যা আপনি মূল ধারণা এবং সাধারণ ব্যবহারের ক্ষেত্রে উল্লেখ করতে পারেন।
আপনি যদি একটি চিটশীট খুঁজছেন, QuickRef থেকে একটি সহায়ক। সিনট্যাক্স স্মরণ করার জন্য এটি একটি ভাল জায়গা এবং তারা বিভিন্ন প্রোগ্রামিং ভাষায় regex সম্পর্কিত ফাংশনগুলির কিছু প্রাথমিক ওভারভিউ প্রদান করে৷
বেশিরভাগ রেজেক্স কৌশলগুলি সমস্ত প্রোগ্রামিং ভাষা এবং সরঞ্জামগুলিতে একই - তবে নির্দিষ্ট সরঞ্জামগুলি অতিরিক্ত বৈশিষ্ট্যগুলি অফার করতে পারে। তাই আপনার জন্য সেরাটি বেছে নিতে আপনি যে টুলটি ব্যবহার করছেন তা নিয়ে কিছু গবেষণা করুন।
আমার চূড়ান্ত পরামর্শ হবে রেজেক্স ব্যবহার করার জন্য জোর করবেন না কারণ আপনি পারেন। অনেক সময় নিয়মিত string.find() কাজটি সম্পন্ন করার জন্য যথেষ্ট। কিন্তু আপনি যদি টার্মিনালে থাকেন, তাহলে আপনি নিশ্চিতভাবে regex দিয়ে অনেক কিছু করতে পারবেন।
আপনি যদি এই ধরনের নিবন্ধ পছন্দ করেন, আপনি আমার ব্লগ বা টুইটারে নজর রাখতে পারেন।
বিনামূল্যে কোড শিখুন. freeCodeCamp-এর ওপেন সোর্স পাঠ্যক্রম 40,000-এরও বেশি লোককে ডেভেলপার হিসেবে চাকরি পেতে সাহায্য করেছে। শুরু করুন