রেজেক্স টেস্টার

রেগুলার এক্সপ্রেশন লাইভ তৈরি ও ডিবাগ করুন। একটি প্যাটার্ন টাইপ করুন, ফ্ল্যাগ টগল করুন, এবং প্রতিটি ম্যাচ আপনার টেস্ট টেক্সটে তার নম্বরযুক্ত ও নামযুক্ত ক্যাপচার গ্রুপসহ নিচে তালিকাভুক্ত হয়ে জ্বলজ্বল করে ওঠে। $1 প্রতিস্থাপনের প্রিভিউ দেখতে রিপ্লেস মোড চালু করুন, কোনো সাধারণ-প্যাটার্ন প্রিসেট লোড করুন, এবং চিটশিটটি কাছে রাখুন। ব্রাউজারের নেটিভ JavaScript RegExp ইঞ্জিন ব্যবহার করে, তাই এটি হুবহু আপনার কোডের মতো আচরণ করে — এবং কিছুই কখনো আপলোড হয় না।

/ /
0 ম্যাচ
আপনি টাইপ করার সাথে সাথে ম্যাচ এখানে হাইলাইট হবে।

কোনো সাধারণ প্যাটার্ন চেষ্টা করুন

কোনো প্রিসেটে ক্লিক করে তার প্যাটার্ন, ফ্ল্যাগ ও একটি নমুনা স্ট্রিং লোড করুন, তারপর তা পরিবর্তন করুন।

রেজেক্স টেস্টার কীভাবে ব্যবহার করবেন

  1. আপনার প্যাটার্ন টাইপ করুন এক্সপ্রেশন বক্সে — চারপাশে স্ল্যাশের প্রয়োজন নেই, শুধু রেজেক্সের মূল অংশ।
  2. আপনার প্রয়োজনের ফ্ল্যাগ বেছে নিন। প্রতিটি ম্যাচ দেখতে g চালু রাখুন; কেস-অসংবেদনশীল ম্যাচিং-এর জন্য i যোগ করুন।
  3. আপনার টেক্সট পেস্ট করুন টেস্ট বক্সে। ম্যাচ সাথে সাথে হাইলাইট হয়, পর্যায়ক্রমে রঙে যাতে পাশাপাশি ম্যাচগুলো সহজে আলাদা চেনা যায়।
  4. গ্রুপ পড়ুন — প্রতিটি ম্যাচ তার নম্বরযুক্ত ও নামযুক্ত ক্যাপচার গ্রুপ তালিকাভুক্ত করে যাতে আপনি নিশ্চিত করতে পারেন সঠিক অংশগুলো বের করছেন।
  5. প্রতিস্থাপনের প্রিভিউ দেখুন — "রিপ্লেস দেখান" চালু করুন এবং টেক্সট পুনর্গঠন করতে $1, $<name> বা $& ব্যবহার করুন।
  6. ফলাফল কপি করুন এবং প্যাটার্নটি সরাসরি আপনার JavaScript, TypeScript বা Node.js কোডে বসান।

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

টোকেনকিসের সাথে ম্যাচ হয়
. নিউলাইন ছাড়া যেকোনো অক্ষর (s ফ্ল্যাগের সাথে নিউলাইনের সাথেও ম্যাচ)।
\d \D একটি অঙ্ক 0–9 / যেকোনো অ-অঙ্ক।
\w \W একটি শব্দ-অক্ষর [A-Za-z0-9_] / যেকোনো অ-শব্দ-অক্ষর।
\s \S যেকোনো ফাঁকা জায়গা (স্পেস, ট্যাব, নিউলাইন) / যেকোনো অ-ফাঁকা-জায়গা।
[abc] [^abc] a, b, c-এর যেকোনো একটি / a, b, c ছাড়া যেকোনো অক্ষর।
[a-z] একটি রেঞ্জ — যেকোনো ছোট হাতের অক্ষর। রেঞ্জ একত্র করুন: [A-Za-z0-9]।
^ $ স্ট্রিং-এর শুরু / শেষ (বা m ফ্ল্যাগের সাথে প্রতিটি লাইনের)।
\b \B একটি শব্দ-সীমানা / এমন একটি অবস্থান যা শব্দ-সীমানা নয়।
* + ? পূর্ববর্তী টোকেনের 0 বা তার বেশি / 1 বা তার বেশি / 0 বা 1।
{n} {n,} {n,m} ঠিক n / n বা তার বেশি / n ও m-এর মধ্যে পুনরাবৃত্তি।
*? +? ?? Lazy (non-greedy) — যত কম অক্ষর সম্ভব তত ম্যাচ করুন।
a|b Alternation — a বা b ম্যাচ করুন।
( ) একটি নম্বরযুক্ত ক্যাপচার গ্রুপ।
(?<name> ) একটি নামযুক্ত ক্যাপচার গ্রুপ, $<name> হিসেবে উল্লেখিত।
(?: ) একটি non-capturing গ্রুপ (ক্যাপচার তৈরি না করেই গ্রুপ করে)।
(?= ) (?! ) Positive / negative lookahead।
(?<= ) (?<! ) Positive / negative lookbehind।
\p{L} \p{N} ইউনিকোড প্রপার্টি এস্কেপ (letter / number) — u ফ্ল্যাগ প্রয়োজন।

নির্ভরযোগ্য রেগুলার এক্সপ্রেশন লেখার পরামর্শ

  • বিশেষ অক্ষর এস্কেপ করুন — একটি আক্ষরিক ডট, প্লাস বা প্রশ্নচিহ্ন \., \+, \? লিখতে হবে। কোনো ক্যারেক্টার ক্লাসের ভেতরে বেশিরভাগ মেটা-অক্ষর তাদের অর্থ হারায়।
  • গ্রিডির চেয়ে সুনির্দিষ্ট ভালো"[^"]*" কোনো উদ্ধৃত স্ট্রিং ".*"-এর চেয়ে নিরাপদভাবে পড়ে, যা এক লাইনে একাধিক স্ট্রিং গিলে ফেলতে পারে।
  • যেখানে সম্ভব অ্যাঙ্কর করুন^$ (বা \b সীমানা) যোগ করা আংশিক ম্যাচ থামায় এবং ইঞ্জিনকে দ্রুত ব্যর্থ হতে সাহায্য করে।
  • নামযুক্ত গ্রুপ ব্যবহার করুন(?<id>\d+) বজায় রাখা $1-এর জন্য বন্ধনী গোনার চেয়ে অনেক সহজ।
  • নেস্টেড কোয়ান্টিফায়ারে খেয়াল রাখুন(a+)+-এর মতো প্যাটার্ন catastrophic backtracking ঘটাতে পারে; এগুলোকে একটিমাত্র ক্যারেক্টার ক্লাসে সমতল করুন।
  • এজ-কেস টেস্ট করুন — খালি ইনপুট, প্রতি লাইনে একাধিক ম্যাচ, এবং সবচেয়ে দীর্ঘ বাস্তব স্ট্রিং। একটি ভালো রেজেক্স সেটাই যা সঠিকভাবে ব্যর্থ হয়, কেবল সেটা নয় যা একবার পাস করে।

রেগুলার এক্সপ্রেশনের সংক্ষিপ্ত ইতিহাস

রেগুলার এক্সপ্রেশনের সূচনা প্রোগ্রামিং থেকে নয়, বরং বিশুদ্ধ গণিত থেকে। 1951 সালে আমেরিকান যুক্তিবিদ Stephen Cole Kleene প্রতীকের অনুক্রমে সরল প্যাটার্ন বর্ণনা করার একটি উপায় আনুষ্ঠানিক রূপ দেন, যাদের তিনি regular events (আজ আমরা regular languages বলি) নামে অভিহিত করেন। তাঁর সংকেতপদ্ধতি সেই অপারেটর চালু করে যা আজও তাঁর নামে পরিচিত — Kleene star, যাকে * লেখা হয়, যার অর্থ "পূর্ববর্তী উপাদানের শূন্য বা তার বেশি"। এই একটি ধারণাই — একটি ছোট, সসীম অভিব্যক্তি দিয়ে স্ট্রিং-এর অসীম সেট বর্ণনা করা — সেই ভিত্তি যার ওপর প্রতিটি রেজেক্স ইঞ্জিন দাঁড়িয়ে আছে।

রেগুলার এক্সপ্রেশন কম্পিউটার পর্যন্ত পৌঁছায় Ken Thompson-এর মাধ্যমে, যিনি Unix-এর সহ-নির্মাতা ছিলেন। 1960-এর দশকের শেষে তিনি Kleene-এর সংকেতপদ্ধতি QED টেক্সট এডিটরে এবং পরে Unix এডিটর ed-তে যুক্ত করেন যাতে ব্যবহারকারীরা প্যাটার্ন দিয়ে ফাইল খুঁজতে পারে। সবচেয়ে বিখ্যাত উত্তরসূরি হলো grep, যার নাম সরাসরি ed কমান্ড g/re/p থেকে আসে — “globally search for a regular expression and print the matching lines”। Thompson 1968 সালে একটি রেগুলার এক্সপ্রেশনকে দ্রুত অনুসন্ধান-কোডে সংকলন করার একটি অ্যালগরিদমও প্রকাশ করেন, এমন কাজ যা আজও আধুনিক উচ্চ-কর্মক্ষমতা ইঞ্জিনগুলোকে ভিত্তি জোগায়।

সেখান থেকে রেজেক্স Unix টুলচেইনে ছড়িয়ে পড়ে — sed, awk, lex — এবং তারপর Perl ভাষার সাথে জনপ্রিয়তায় বিস্ফোরণ ঘটে, যা শক্তিশালী প্যাটার্ন ম্যাচিংকে একটি প্রথম-শ্রেণির বৈশিষ্ট্য করে তোলে। Perl-এর উপভাষা এতটাই প্রভাবশালী হয় যে 1997 সালে Philip Hazel PCRE (Perl Compatible Regular Expressions) তৈরি করেন, একটি C লাইব্রেরি যা এখন PHP, Apache ও Nginx ওয়েব সার্ভার এবং অগণিত অন্যান্য টুলে সন্নিবেশিত। সমান্তরালে, 1992 সালের POSIX.2 মানদণ্ড দুটি পোর্টেবল ফ্লেভার সংজ্ঞায়িত করে — Basic ও Extended Regular Expressions — যা Unix ইউটিলিটি আজও অনুসরণ করে। আপনার ব্রাউজারের ইঞ্জিন, ECMAScript-এর RegExp, আবার একটি পৃথক বংশ, যা JavaScript-এর অংশ হিসেবে মানকীকৃত।

ইঞ্জিনের পেছনের তত্ত্ব

একটি “regular” ভাষা ঠিক সেটিই যা একটি সসীম অটোমেটন (finite automaton) — নির্দিষ্ট সংখ্যক অবস্থা ও কোনো অতিরিক্ত মেমরিহীন একটি মেশিন — চিনতে পারে। প্রতিটি রেগুলার এক্সপ্রেশনকে এমন মেশিনে রূপান্তর করা যায়, এবং আবার ফিরিয়েও; দুটি গাণিতিকভাবে সমতুল্য। Thompson’s construction কোনো প্যাটার্নকে একটি nondeterministic finite automaton (NFA)-তে পরিণত করে, যাকে তারপর একটি deterministic finite automaton (DFA)-তে রূপান্তর করা যায় যা প্রতিটি ইনপুট অক্ষর ঠিক একবার পড়ে।

এই তত্ত্ব ব্যাখ্যা করে কেন রেজেক্স ইঞ্জিনের দুটি খুব ভিন্ন পরিবার রয়েছে। অটোমেটন (DFA-শৈলী) ইঞ্জিন — যা grep, Google-এর RE2 ও Rust-এর regex crate ব্যবহার করে — প্যাটার্ন যতই খারাপ হোক না কেন, রৈখিক সময়ে ম্যাচিং-এর নিশ্চয়তা দেয়, তবে কিছু সুবিধাজনক বৈশিষ্ট্য দিতে পারে না। ব্যাকট্র্যাকিং ইঞ্জিন — যা Perl, PCRE, Python, Java, .NET ও JavaScript ব্যবহার করে — সম্ভাবনাগুলো চেষ্টা ও ভুলের মাধ্যমে খুঁজে বের করে, যা তাদের backreferences ও lookaround সমর্থন করতে দেয়, তবে কখনো কখনো catastrophic ধীরগতির মূল্যে (নিচে দেখুন)। আপনি যখন এখানে কোনো প্যাটার্ন টেস্ট করেন তখন আপনি একটি ব্যাকট্র্যাকিং ইঞ্জিন চালাচ্ছেন, এবং এটি বোঝা এমন প্যাটার্ন লেখার চাবিকাঠি যা দ্রুত থাকে।

রেজেক্স ফ্লেভার: JavaScript কীভাবে ভিন্ন

কোনো একক রেগুলার-এক্সপ্রেশন ভাষা নেই — অনেকগুলো ঘনিষ্ঠ-সম্পর্কিত উপভাষা আছে, এবং একটি প্যাটার্ন যা একটিতে চমৎকার কাজ করে তা অন্যটিতে ভিন্ন আচরণ করতে পারে, বা ব্যর্থ হতে পারে। এই টেস্টার ECMAScript (JavaScript) ইঞ্জিন চালায়, সেটিই যা Node.js ও প্রতিটি ব্রাউজারে আছে, তাই আপনি এখানে যা দেখেন তা-ই আপনার JavaScript বা TypeScript কোড করবে।

ফ্লেভারযেখানে এটি পাবেনউল্লেখযোগ্য বৈশিষ্ট্য
POSIX BRE / EREgrep, sed, শেল টুলBRE-এর গ্রুপের জন্য \( প্রয়োজন; ERE এস্কেপ ছাড়াই + ? | যোগ করে।
PCRE / PerlPHP, Nginx, অনেক এডিটরসবচেয়ে সমৃদ্ধ উপভাষা: atomic groups, possessive quantifiers, recursion।
Python rePython স্ক্রিপ্টইনলাইন ফ্ল্যাগ ও নামযুক্ত গ্রুপ (?P<name>…) হিসেবে লেখা হয়।
.NET / JavaC#, Java অ্যাপ্লিকেশনঅতিরিক্ত বৈশিষ্ট্যসহ ব্যাকট্র্যাকিং; .NET প্রতি-ম্যাচ টাইমআউট সমর্থন করে।
ECMAScriptএই টুল, ব্রাউজার, Node.jsকোনো atomic groups বা possessive quantifiers নেই; নামযুক্ত গ্রুপ (?<name>…) ব্যবহার করে।

JavaScript-এর ইঞ্জিন দ্রুত পরিপক্ব হয়েছে। u (unicode) ও y (sticky) ফ্ল্যাগ ES2015-তে আসে। ES2018 ছিল একটি যুগান্তকারী রিলিজ যা নামযুক্ত ক্যাপচার গ্রুপ (?<name>…), lookbehind assertions (?<=…)(?<!…), s (dotAll) ফ্ল্যাগ, এবং ইউনিকোড প্রপার্টি এস্কেপ যেমন \p{L} যোগ করে। সাম্প্রতিককালে match indices-এর জন্য d ফ্ল্যাগ (ES2022) এবং বর্ধিত ইউনিকোড সেটের জন্য v ফ্ল্যাগ (ES2024) যোগ হয়েছে। PCRE-এর তুলনায় JavaScript-এ এখনও যা নেই তা হলো possessive quantifiers (a++) ও atomic groups ((?>…)) — সেই উপকরণগুলোই যা অন্য ভাষাগুলো দৌড়ানো ব্যাকট্র্যাকিং থামাতে ব্যবহার করে, এ কারণেই পরবর্তী অংশটি JS ডেভেলপারদের জন্য এত গুরুত্বপূর্ণ।

গ্রিডি, লেজি এবং ম্যাচিং কীভাবে এগোয়

ইঞ্জিন আপনার টেক্সটের মধ্য দিয়ে কীভাবে হাঁটে তা বোঝা রেজেক্সকে অনুমান থেকে একটি পূর্বানুমেয় উপকরণে পরিণত করে। ডিফল্টভাবে প্রতিটি কোয়ান্টিফায়ার গ্রিডি (greedy): *, +? যত টেক্সট পারে তত ধরে রাখে, তারপর একটি একটি করে অক্ষর ফিরিয়ে দেয় (এই ফিরিয়ে দেওয়াই ব্যাকট্র্যাকিং) যতক্ষণ না বাকি প্যাটার্ন ম্যাচ করতে পারে। তাই ".*" যখন he said "one" then "two"-তে প্রয়োগ করা হয় তখন প্রথম উদ্ধৃতি থেকে শেষ উদ্ধৃতি পর্যন্ত সম্পূর্ণ অংশ ম্যাচ করে, কারণ গ্রিডি .* নত হওয়ার আগে সবকিছু গিলে ফেলে।

কোনো কোয়ান্টিফায়ারকে লেজি (lazy, non-greedy) করতে তাতে ? যোগ করুন: ".*?" যত কম সম্ভব তত ম্যাচ করে, প্রথম বন্ধ উদ্ধৃতিতে থেমে, তাই এটি কেবল "one" ধরে। প্রায়ই পরিষ্কার সমাধান হলো একটি নেগেটেড ক্যারেক্টার ক্লাস (negated character class): "[^"]*" বলে “একটি উদ্ধৃতি, তারপর অ-উদ্ধৃতি অক্ষরের কোনো ধারা, তারপর একটি উদ্ধৃতি”, যা অস্পষ্টতা-মুক্তও এবং দ্রুতও কারণ একে কখনো ব্যাকট্র্যাক করতে হয় না। গ্রিডি বনাম লেজি বনাম নেগেটেড ক্লাস বেছে নেওয়া বাস্তব প্যাটার্নে সবচেয়ে সাধারণ সিদ্ধান্তগুলোর একটি, এবং ওপরের লাইভ হাইলাইটিং এই পার্থক্য দেখা সহজ করে দেয়।

Catastrophic backtracking এবং ReDoS

যেহেতু JavaScript একটি ব্যাকট্র্যাকিং ইঞ্জিন ব্যবহার করে, একটি অসাবধান প্যাটার্ন কিছু ইনপুটে সূচকীয় (exponential) সময় নিতে পারে — একটি সত্যিকারের নিরাপত্তা ত্রুটি যাকে regular-expression denial of service (ReDoS) বলা হয়। সমস্যা তখন দেখা দেয় যখন কোনো পুনরাবৃত্ত গ্রুপ একই টেক্সটকে একাধিক ওভারল্যাপিং উপায়ে ম্যাচ করতে পারে এবং তারপর সম্পূর্ণ ম্যাচ ব্যর্থ হয়। পাঠ্যপুস্তকের উদাহরণ হলো (a+)+$, যাকে a অক্ষরের একটি দীর্ঘ স্ট্রিং-এর বিপরীতে টেস্ট করা হয় যার পরে এমন একটি অক্ষর থাকে যা ম্যাচ করতে পারে না: ইঞ্জিন a-গুলোকে ভেতরের ও বাইরের +-এর মধ্যে ভাগ করার প্রতিটি উপায় চেষ্টা করে, এবং সংযোজনের সংখ্যা প্রতিটি অতিরিক্ত অক্ষরের সাথে প্রায় দ্বিগুণ হয়। কয়েক ডজন অক্ষর একটি ট্যাবকে — বা কোনো সার্ভারে, একটি সম্পূর্ণ রিকোয়েস্ট থ্রেডকে — জমিয়ে দিতে পারে।

Perl ও PCRE-এর মতো ভাষা একে atomic groupspossessive quantifiers দিয়ে নিষ্ক্রিয় করে যা ইঞ্জিনকে কোনো গ্রুপে ফিরে ব্যাকট্র্যাক করা থেকে বিরত রাখে। JavaScript-এর দুটির কোনোটিই নেই, তাই আপনাকে বিপদটি ডিজাইন থেকেই সরাতে হবে:

  • ওভারল্যাপিং টেক্সটে কখনো কোয়ান্টিফায়ার নেস্ট করবেন না। (a+)+-কে একটিমাত্র a+ হিসেবে, এবং (\w+\s?)+-কে [\w\s]+ হিসেবে আবার লিখুন।
  • পুনরাবৃত্ত অংশগুলোকে পারস্পরিক-বর্জনশীল করুন। কোনো (.*a)-শৈলীর লুপকে ([^a]*a)-তে পরিণত করা সেই ওভারল্যাপ সরিয়ে দেয় যা ব্যাকট্র্যাকিংকে উসকে দেয়।
  • অ্যাঙ্কর করুন এবং সুনির্দিষ্ট হোন। সীমানা (^, $, \b) ও কঠোর ক্যারেক্টার ক্লাস ইঞ্জিনকে মৃত পথ খোঁজার বদলে দ্রুত ব্যর্থ হতে দেয়।
  • আপনার ইনপুট সীমাবদ্ধ করুন। যে স্ট্রিং-এর বিপরীতে আপনি অবিশ্বস্ত প্যাটার্ন টেস্ট করেন তার দৈর্ঘ্য সীমিত করুন, এবং ব্যবহারকারী-সরবরাহকৃত প্যাটার্নের সার্ভার-সাইড ম্যাচিং-এর জন্য রৈখিক-সময় লাইব্রেরি (Google-এর RE2, Rust-এর regex crate)-কে প্রাধান্য দিন।

একটি উপযোগী নিয়ম: যদি কোনো প্যাটার্ন এই টেস্টারে ধীর মনে হয়, তবে এটি প্রোডাকশনেও ধীর — এবং শোষণ-যোগ্য — হবে। এখানকার ম্যাচ কাউন্টার পৃষ্ঠাটিকে প্রতিক্রিয়াশীল রাখতে তার পুনরাবৃত্তি সীমিত রাখে, তবে সেই নিরাপত্তা-জাল আপনার অ্যাপ্লিকেশন কোডে থাকে না।

রেগুলার এক্সপ্রেশন কীসে ভালো (এবং কীসে খারাপ)

রেজেক্স সমতল, লাইন-ভিত্তিক টেক্সট খোঁজা, যাচাই, বের করা ও প্রতিস্থাপন করার সঠিক উপকরণ: কোনো লগে প্রতিটি ইমেল-আকৃতির স্ট্রিং খোঁজা, কোনো রিপোর্ট থেকে তারিখ বের করা, কোনো সীমাবদ্ধ লাইন ভাগ করা বা একটি টোকেনকে অন্যটি দিয়ে বদলানো। এটি তখন উৎকৃষ্ট হয় যখন গঠন স্থানীয় ও পূর্বানুমেয়।

এটি গভীরভাবে নেস্টেড বা পুনরাবৃত্ত (recursive) কোনো কিছুর জন্য ভুল উপকরণ। যে তত্ত্ব রেগুলার ভাষাগুলোকে দ্রুত করে, সেটিই তাদের যথেচ্ছ নেস্টিং গুনতে অক্ষমও করে তোলে — একটি সসীম অটোমেটনের কতগুলো ব্র্যাকেট এখনও খোলা তা ট্র্যাক করার মেমরি নেই। এটাই সেই প্রসিদ্ধ সতর্কতার আসল কারণ যে রেগুলার এক্সপ্রেশন দিয়ে কখনো HTML পার্স করবেন না: HTML, XML ও JSON নেস্টেড ব্যাকরণ, এবং একটি প্যাটার্ন যা কাজ করছে বলে মনে হয় তা প্রথম কমেন্ট, নেস্টেড ট্যাগ বা এজ-কেসে ভেঙে পড়বে। এর বদলে কোনো নিবেদিত পার্সার ব্যবহার করুন (ব্রাউজারের DOMParser, বা JSON-এর জন্য JSON.parse)।

ইমেল ক্লাসিক অতি-প্রসারণ। একটি প্যাটার্ন যা RFC 5322 ঠিকানা ব্যাকরণ সম্পূর্ণ বাস্তবায়ন করে তা শত শত অক্ষর দীর্ঘ এবং তবুও নিশ্চিত করতে পারে না যে কোনো ঠিকানা সত্যিই মেল গ্রহণ করে। বাস্তবে [^@\s]+@[^@\s]+\.[^@\s]+-এর মতো একটি সরল যাচাই এবং একটি বাস্তব নিশ্চিতকরণ ইমেল যেকোনো দানবীয় রেজেক্সের চেয়ে ভালো। এই শিক্ষা সাধারণীকৃত হয়: রেজেক্স তুলুন যখন প্যাটার্ন সত্যিই রেগুলার, এবং যখন নয় তখন কোনো পার্সার বা উদ্দেশ্য-নির্মিত লাইব্রেরির দিকে যান।

Lookaround ও backreferences: প্রসঙ্গে ম্যাচিং

দুটি বৈশিষ্ট্য কোনো প্যাটার্নকে তার পরিবেশ পরিদর্শন করতে দেয় তা গ্রহণ না করেই। একটি lookahead দাবি করে যে সামনে যা আছে তা ম্যাচ করে ((?=…)) বা করে না ((?!…)), এবং একটি lookbehind আগে যা আছে তার জন্য একই কাজ করে ((?<=…)(?<!…))। উদাহরণস্বরূপ, \d+(?= kg) কোনো সংখ্যাকে কেবল তখনই ম্যাচ করে যখন তার পরে “ kg” থাকে, তবুও “ kg” নিজে ম্যাচের বাইরে থাকে — তখন উপযোগী যখন আপনি কোনো মান খুঁজতে চান কিন্তু তার এককটিকে ধরা টেক্সটের বাইরে রাখতে চান। JavaScript ES2018 থেকে lookbehind সমর্থন করে, তাই এই টেস্টারে দুই দিকই কাজ করে।

একটি backreference কোনো আগের গ্রুপ যা ধরেছে তা আবার ব্যবহার করে। প্যাটার্নের ভেতরে, \1-এর অর্থ “সেই একই টেক্সট যা গ্রুপ 1 এইমাত্র ম্যাচ করেছে”, তাই (\w+)\s+\1 “the the”-এর মতো একটি পুনরাবৃত্ত শব্দ খোঁজে, এবং \k<name> কোনো নামযুক্ত গ্রুপের জন্য একই কাজ করে। Backreferences সেই বৈশিষ্ট্যগুলোর একটি যা একটি বিশুদ্ধ অটোমেটন ইঞ্জিন দিতে পারে না, ঠিক এ কারণেই JavaScript একটি ব্যাকট্র্যাকিং ইঞ্জিন ব্যবহার করে — এবং এ কারণেই ওপরের catastrophic-backtracking সতর্কতাগুলো আপনার শিপ করা প্রতিটি জিনিসে প্রযোজ্য।

প্রায়শই জিজ্ঞাসিত প্রশ্ন

এই টেস্টার কোন রেজেক্স সিনট্যাক্স ব্যবহার করে?

এটি ব্রাউজারের নেটিভ JavaScript (ECMAScript) রেগুলার-এক্সপ্রেশন ইঞ্জিন ব্যবহার করে — ঠিক সেই RegExp বাস্তবায়ন যাতে আপনার কোড Node.js, Deno ও প্রতিটি আধুনিক ব্রাউজারে চলে। এর অর্থ হলো এখানে আপনি যে প্যাটার্ন টেস্ট করেন সেগুলো প্রোডাকশন JavaScript-এ হুবহু একইভাবে আচরণ করে। JavaScript রেজেক্স PCRE (PHP/Perl), Python-এর re, Java ও .NET থেকে ছোট ছোট উপায়ে ভিন্ন — যেমন JavaScript-এ ইনলাইন (?i) মডিফায়ার নেই, কোনো possessive কোয়ান্টিফায়ার নেই, এবং নামযুক্ত গ্রুপ (?<name>…) সিনট্যাক্স ব্যবহার করে। আপনি যদি অন্য কোনো ভাষার জন্য লিখছেন তবে এই এজ-কেসগুলো আবার যাচাই করুন, তবে যেকোনো JS/TypeScript-এর জন্য এটি প্রামাণিক।

ফ্ল্যাগ g, i, m, s, u ও y-এর মানে কী?

g (গ্লোবাল) প্রথম ম্যাচে না থেমে প্রতিটি ম্যাচ খুঁজে বের করে। i (ইগনোর কেস) প্যাটার্নকে কেস-অসংবেদনশীল করে তোলে। m (মাল্টিলাইন) ^ ও $-কে সম্পূর্ণ স্ট্রিং-এর বদলে প্রতিটি লাইনের শুরু ও শেষের সাথে ম্যাচ করায়। s (dotAll) . -কে নিউলাইন অক্ষরের সাথেও ম্যাচ করতে দেয়। u (ইউনিকোড) সম্পূর্ণ ইউনিকোড হ্যান্ডলিং সক্ষম করে, যার মধ্যে \p{…} প্রপার্টি এস্কেপ ও সঠিক surrogate-pair ম্যাচিং অন্তর্ভুক্ত। y (স্টিকি) প্রতিটি ম্যাচকে ঠিক আগের ম্যাচের পরের অবস্থানে (lastIndex) অ্যাঙ্কর করে। আপনি এদের যেকোনোগুলো একত্র করতে পারেন — g বা y চালু থাকলে এই টেস্টার সব ম্যাচ দেখায়, অন্যথায় কেবল প্রথম ম্যাচ, ঠিক যেভাবে RegExp.prototype.exec আসলে আচরণ করে।

ক্যাপচার গ্রুপ ও নামযুক্ত গ্রুপ কীভাবে কাজ করে?

বন্ধনী ( ) একটি নম্বরযুক্ত ক্যাপচার গ্রুপ তৈরি করে; প্রতিটি গ্রুপ যে টেক্সট ম্যাচ করেছে তা প্রতিটি ফলাফলের নিচে Group 1, Group 2 ইত্যাদি হিসেবে সেই ক্রমে দেখানো হয় যে ক্রমে খোলা বন্ধনী আসে। কোনো গ্রুপকে নাম দিতে (?<year>\d{4}) ব্যবহার করুন — নামযুক্ত গ্রুপ ফলাফলে নাম দিয়ে দেখা যায় এবং কোনো প্রতিস্থাপনে $<year> হিসেবে উল্লেখ করা যায়। একটি non-capturing গ্রুপ (?:…) প্যাটার্নের কোনো অংশকে কোনো কোয়ান্টিফায়ার বা alternation-এর জন্য নম্বরযুক্ত ক্যাপচার তৈরি না করেই গ্রুপ করে, যা আপনার গ্রুপ নম্বরগুলো পরিষ্কার রাখে এবং সামান্য দ্রুতও।

আমি রিপ্লেস ফিচারটি কীভাবে ব্যবহার করব?

"রিপ্লেস দেখান" চালু করুন এবং একটি প্রতিস্থাপন স্ট্রিং টাইপ করুন। নম্বরযুক্ত ক্যাপচার গ্রুপ ঢোকাতে $1, $2 …, নামযুক্ত গ্রুপের জন্য $<name>, সম্পূর্ণ ম্যাচের জন্য $&, এবং একটি আক্ষরিক ডলার চিহ্নের জন্য $$ ব্যবহার করুন। উদাহরণস্বরূপ, প্যাটার্ন (\w+)\s(\w+)-এর সাথে প্রতিস্থাপন $2 $1 দুটি শব্দকে অদলবদল করে দেয়। প্রতিস্থাপন আপনার ফ্ল্যাগ মেনে চলে: g ফ্ল্যাগ ছাড়া কেবল প্রথম ম্যাচ প্রতিস্থাপিত হয়। আউটপুট String.prototype.replace দিয়ে গণনা করা হয়, তাই এটি আপনার কোডের সাথে হুবহু মেলে।

আমার রেজেক্স "Catastrophic backtracking" দেখাচ্ছে কেন বা ধীরে চলছে কেন?

ওভারল্যাপিং টেক্সটে নেস্টেড কোয়ান্টিফায়ারযুক্ত প্যাটার্ন — ক্লাসিকভাবে (a+)+, (.*)*, বা কোনো দীর্ঘ না-ম্যাচ-হওয়া স্ট্রিং-এর বিপরীতে (\w+\s?)+ — ইঞ্জিনকে সূচকীয় (exponential) সংখ্যক পথ চেষ্টা করাতে বাধ্য করতে পারে, যা ট্যাবটিকে জমিয়ে দেয়। একে catastrophic backtracking বলা হয় এবং এটি প্রোডাকশনে একটি সত্যিকারের denial-of-service ঝুঁকি (ReDoS)। এটি ঠিক করুন: প্যাটার্নকে অ্যাঙ্কর করুন, নেস্টেড গ্রুপকে একটিমাত্র ক্যারেক্টার ক্লাস দিয়ে প্রতিস্থাপন করুন (যেমন (\w+\s?)+-এর বদলে [\w\s]+), বা সীমানা যোগ করুন যাতে ইঞ্জিন দ্রুত ব্যর্থ হতে পারে। এই টেস্টার প্রতিক্রিয়াশীল থাকতে পুনরাবৃত্তি (iteration) সীমিত রাখে, তবে যে প্যাটার্ন এখানে ধীর তা আপনার অ্যাপেও ধীর থাকবে।

আমার প্যাটার্ন বা টেস্ট টেক্সট কি কোথাও আপলোড হয়?

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

আরও টুল দেখুন

সব 70টি টুল দেখুন →