রেজেক্স চিট শিট

JavaScript ফ্লেভারের জন্য একটি সার্চযোগ্য রেগুলার এক্সপ্রেশন চিট শিট: ক্যারেক্টার ক্লাস, ব্র্যাকেট সেট, কোয়ান্টিফায়ার, অ্যাংকর, লুকঅ্যারাউন্ড, গ্রুপ এবং ফ্ল্যাগ, প্রতিটির সাথে একটি উদাহরণ।

উদাহরণসহ একচল্লিশটি রেজেক্স টোকেন। টোকেন, বর্ণনা এবং উদাহরণ জুড়ে ফিল্টার করুন, তারপর আপনার প্রয়োজনীয় সিনট্যাক্স কপি করুন। ব্রাউজার এবং Node.js-এ ব্যবহৃত JavaScript (ECMAScript) ফ্লেভার কভার করে।

আত্মবিশ্বাসের সাথে রেগুলার এক্সপ্রেশন পড়া ও লেখা

একটি সিনট্যাক্স টেবিল, টিউটোরিয়াল নয়

রেগুলার এক্সপ্রেশন ডিজাইনের মাধ্যমেই ঘন। ^(?:\d{1,3}\.){3}\d{1,3}$ এর মতো একটি প্যাটার্ন একটি সম্পূর্ণ IPv4 ভ্যালিডেটরকে ত্রিশটি অক্ষরে ভরে দেয়, যা আপনি যখন এটি লিখেছেন তখন চমৎকার এবং যখন আপনি অন্যের লেখা পড়ছেন তখন দুঃখজনক। বেশিরভাগ কঠিনতা ধারণাগত নয় — এটি হলো শব্দভাণ্ডারটি বড়, সংক্ষিপ্ত এবং সহজে অর্ধেক মনে রাখা যায়।

এই পৃষ্ঠাটি সেই শব্দভাণ্ডারের জন্য একটি লুকআপ টেবিল, যা প্যাটার্নগুলো যেভাবে আসলে তৈরি হয় সেভাবে সংগঠিত: কী একটি একক অক্ষর মেলে, কীভাবে আপনার নিজের ক্যারেক্টার সেট সংজ্ঞায়িত করবেন, কীভাবে "এটি পুনরাবৃত্তি করুন" বলবেন, ম্যাচটি কোথায় অ্যাংকর করবেন, কীভাবে গ্রুপ ও অল্টারনেট করবেন এবং কোন ফ্ল্যাগ ইঞ্জিনের আচরণ পরিবর্তন করে। ফিল্টারটি টোকেন, বর্ণনা এবং উদাহরণ একসাথে খোঁজে, তাই "lazy", "boundary" বা "lookbehind" টাইপ করলে সরাসরি সেই সারিতে যায় যা আপনি অর্ধেক মনে রেখেছেন।

এই টোকেনগুলো কোন ফ্লেভার অনুসরণ করে

রেগুলার এক্সপ্রেশন একটি ভাষা নয়। Grep, PCRE, Python, Java, Go-এর RE2 এবং JavaScript সবাই একটি সাধারণ মূল ভাগ করে কিন্তু প্রান্তে দ্বিমত পোষণ করে। এখানে তালিকাভুক্ত সবকিছু ECMAScript দ্বারা সংজ্ঞায়িত JavaScript ফ্লেভারকে লক্ষ্য করে, কারণ ব্রাউজার, Node.js এবং বেশিরভাগ ফ্রন্ট-এন্ড টুলিংয়ে এটিই চলে।

তিনটি পার্থক্য উল্লেখযোগ্য। প্রথমত, lookbehind — (?<=...) এবং (?<!...) — আধুনিক JavaScript ইঞ্জিনে সমর্থিত কিন্তু Go-এর RE2 এবং পুরোনো Safari সংস্করণ থেকে অনুপস্থিত, তাই এটির উপর নির্ভরশীল প্যাটার্নগুলো সর্বত্র বহনযোগ্য নয়। দ্বিতীয়ত, JavaScript-এ কোনো x ভার্বোজ ফ্ল্যাগ নেই, তাই আপনি Python-এর মতো মন্তব্যসহ একাধিক লাইনে প্যাটার্ন ছড়াতে পারবেন না; দীর্ঘ প্যাটার্ন সাধারণত স্ট্রিং খণ্ড থেকে একত্রিত হয়। তৃতীয়ত, \d এবং \w ডিফল্টরূপে JavaScript-এ শুধুমাত্র ASCII, তাই \w উচ্চারিত অক্ষর বা CJK অক্ষরের সাথে মেলে না যতক্ষণ না আপনি u ফ্ল্যাগসহ \p{L} এর মতো ইউনিকোড প্রপার্টি এসকেপ ব্যবহার করেন।

স্থায়ীভাবে রক্ষণাবেক্ষণযোগ্য প্যাটার্ন লেখা

দুটি অভ্যাস বেশিরভাগ রেজেক্স ব্যথা প্রতিরোধ করে। প্রথমটি হলো ইচ্ছাকৃতভাবে অ্যাংকর করা। একটি অ-অ্যাংকর্ড প্যাটার্ন স্ট্রিংয়ের যেকোনো জায়গায় ম্যাচ খোঁজে, যা স্ক্যান করার সময় আপনি চান এবং ভ্যালিডেট করার সময় প্রায় কখনোই চান না। ^ এবং $ যোগ করলে "তারিখের মতো দেখতে কিছু" "একটি তারিখ" হয়ে যায়, এবং সেই পার্থক্যটি আশ্চর্যজনক সংখ্যক ভ্যালিডেশন বাগের পিছনে।

দ্বিতীয়টি হলো লোভী ওয়াইল্ডকার্ডের উপরে অলসতা এবং নেগেটেড ক্যারেক্টার ক্লাস পছন্দ করা। ক্লাসিক ভুলটি হলো HTML-সদৃশ টেক্সটে <.+>: কারণ + লোভী, এটি লাইনের শেষ > পর্যন্ত সবকিছু গিলে ফেলে। <.+?> বা আরও ভালোভাবে <[^>]+> লেখা একটি একক ট্যাগ মেলে। নেগেটেড-ক্লাস সংস্করণটি যথেষ্ট দ্রুতও, কারণ ইঞ্জিনকে কখনো ব্যাকট্র্যাক করতে হয় না।

অবশেষে, বিপর্যয়কর ব্যাকট্র্যাকিং সম্পর্কে সচেতন থাকুন। (a+)+b-এর মতো নেস্টেড কোয়ান্টিফায়ার ইঞ্জিনকে ম্যাচ নেই এই সিদ্ধান্ত নেওয়ার আগে ইনপুট ভাগ করার সূচকীয়ভাবে অনেক উপায় অন্বেষণ করতে বাধ্য করতে পারে, যা প্যাটার্নটি ব্যবহারকারীর ইনপুট স্পর্শ করলে একটি ভ্যালিডেশন কলকে ডিনায়াল-অফ-সার্ভিস ভেক্টরে পরিণত করে। যদি একটি প্যাটার্নে একটি কোয়ান্টিফায়ারযুক্ত গ্রুপ থাকে যেটিতে নিজেই একটি কোয়ান্টিফায়ার থাকে, এটি পুনরায় লিখুন — সাধারণত একটি একক ক্যারেক্টার ক্লাস একটি কোয়ান্টিফায়ারসহ রৈখিক সময়ে একই কাজ করে। এবং যখন একটি প্যাটার্ন এক বা দুটি লাইনের বেশি হয়, সৎ উত্তরটি প্রায়ই হয় যে একটি প্রকৃত পার্সার সঠিক টুল এবং রেজেক্সটি নয়।

অভ্যন্তরীণভাবে তৈরি। সিনট্যাক্স টেবিলটি JavaScript (ECMAScript) রেগুলার এক্সপ্রেশন ফ্লেভারকে লক্ষ্য করে এবং সম্পূর্ণ আপনার ব্রাউজারে চলে।

সচরাচর জিজ্ঞাসিত প্রশ্ন

এই টোকেনগুলো কোন রেজেক্স ফ্লেভার বর্ণনা করে?
JavaScript (ECMAScript) ফ্লেভার, যা ব্রাউজার, Node.js এবং বেশিরভাগ ফ্রন্ট-এন্ড টুলিংয়ে চলে। মূল সিনট্যাক্স PCRE, Python এবং Java-এর সাথে ভাগ করা হয়, তাই এই টোকেনগুলোর বিশাল সংখ্যাগরিষ্ঠ সরাসরি স্থানান্তরযোগ্য, কিন্তু অন্য একটি ইঞ্জিনকে লক্ষ্য করলে lookbehind এবং ইউনিকোড প্রপার্টি এসকেপ পরীক্ষা করুন।
কেন আমার প্যাটার্ন আমার প্রত্যাশার চেয়ে বেশি মেলে?
প্রায় সবসময় কারণ একটি কোয়ান্টিফায়ার লোভী। * এবং + উভয়ই যতটা পারে তত নেয় এবং বাকি প্যাটার্ন ব্যর্থ হলে শুধুমাত্র অক্ষর ফেরত দেয়। .+? এর মতো সেগুলোকে অলস করতে ? যোগ করুন, অথবা [^>]+ এর মতো নেগেটেড ক্লাস দিয়ে ওয়াইল্ডকার্ড প্রতিস্থাপন করুন, যা আরও সুনির্দিষ্ট এবং দ্রুত উভয়ই।
ক্যাপচারিং এবং নন-ক্যাপচারিং গ্রুপের মধ্যে পার্থক্য কী?
(abc) যা মিলেছে তা সংরক্ষণ করে যাতে আপনি পরে \1 দিয়ে এটি উল্লেখ করতে পারেন বা ফলাফল অ্যারে থেকে পড়তে পারেন। (?:abc) কোয়ান্টিফায়ার বা অল্টারনেশনের জন্য টোকেনগুলো গ্রুপ করে কিছু সংরক্ষণ না করেই। শুধুমাত্র গ্রুপিংয়ের প্রয়োজন হলে নন-ক্যাপচারিং ফর্মটি ব্যবহার করুন; এটি ফলাফল সূচক স্থিতিশীল রাখে এবং ওভারহেড সামান্য হ্রাস করে।
কেন \w উচ্চারিত বা চীনা অক্ষরের সাথে মেলে না?
JavaScript-এ \w কে [A-Za-z0-9_] হিসাবে সংজ্ঞায়িত করা হয় এবং ইচ্ছাকৃতভাবে শুধুমাত্র ASCII। যেকোনো লিপির অক্ষর মেলাতে, u ফ্ল্যাগসহ একটি ইউনিকোড প্রপার্টি এসকেপ ব্যবহার করুন: /\p{L}+/u ল্যাটিন, সিরিলিক, গ্রিক, হ্যান, কানা এবং প্রতিটি অন্যান্য লিপির অক্ষর মেলে।
একটি রেগুলার এক্সপ্রেশন কি নিরাপত্তা ঝুঁকি হতে পারে?
হ্যাঁ। (a+)+b এর মতো নেস্টেড কোয়ান্টিফায়ার বিপর্যয়কর ব্যাকট্র্যাকিং ট্রিগার করতে পারে, যেখানে ইঞ্জিন ব্যর্থ হওয়ার আগে সূচকীয়ভাবে অনেক সম্ভাবনা অন্বেষণ করে। যদি এমন একটি প্যাটার্ন ব্যবহারকারীর ইনপুটে প্রয়োগ করা হয়, একটি সংক্ষিপ্ত তৈরি স্ট্রিং প্রক্রিয়াটি জমে যেতে পারে। যেখানে সম্ভব নেস্টেড কোয়ান্টিফায়ারগুলোকে একটি একক ক্যারেক্টার ক্লাসে পুনরায় লিখুন।
HTML বা JSON পার্স করতে কি আমার রেজেক্স ব্যবহার করা উচিত?
না। উভয়ই পুনরাবৃত্তিমূলক ফর্ম্যাট এবং রেগুলার এক্সপ্রেশন নির্বিচারে নেস্টিং প্রকাশ করতে পারে না। একটি প্রকৃত পার্সার ব্যবহার করুন: HTML-এর জন্য DOMParser, JSON-এর জন্য JSON.parse। সমতল টেক্সট স্ক্যান করা, সাধারণ ফিল্ড ফর্ম্যাট ভ্যালিডেট করা এবং লক্ষ্যবস্তু ফাইন্ড-এন্ড-রিপ্লেস করার জন্য রেগুলার এক্সপ্রেশন সঠিক টুল।