در عبارات منظم (Regex)، براکتها [ ] یکی از مفاهیم پایهای و پرکاربرد هستند. این ابزار به شما اجازه میدهد تا یک «کلاس کاراکتر» (Character Class) تعریف کنید؛ یعنی به جای جستجوی یک کاراکتر ثابت، مجموعهای از گزینههای ممکن را برای یک موقعیت خاص مشخص کنید. درک صحیح این قابلیت، در کنار سایر متاکاراکترها و دستورات اصلی رجکس، برای فیلتر کردن متن و اعتبارسنجی دقیق دادهها ضروری است.
در این مقاله، ما به شکل کامل و گام به گام، تمام جنبههای استفاده از براکتها، از تعریف بازهها گرفته تا نفی کردن مجموعهها و کار با کاراکترهای ویژه در داخل آنها را بررسی میکنیم.
۲. جدول کاربردی (خلاصه دستورات اصلی)
این جدول برای مرور سریع دستورات اصلی مرتبط با براکتها [ ] طراحی شده است.
| دستور (Pattern) | توضیح کاربردی |
| [abc] | تطبیق مجموعه: یکی از کاراکترهای ‘a’ یا ‘b’ یا ‘c’ را پیدا میکند. |
| [a-z] | تطبیق بازه (Range): یکی از حروف کوچک انگلیسی (از a تا z) را پیدا میکند. |
| [^abc] | نفی کردن (Negation): هر کاراکتری را پیدا میکند که ‘a’، ‘b’ یا ‘c’ نباشد. |
| [a-zA-Z0-9] | ترکیب بازهها: یکی از حروف انگلیسی (کوچک یا بزرگ) یا یک عدد. |
| [\d\s] | ترکیب میانبر: یکی از کاراکترهایی که یا عدد (\d) یا فاصله (\s) باشد. |
| [az-] یا [-az] | کاراکتر لغوی: یکی از کاراکترهای ‘a’، ‘z’ یا خط تیره (-). |
براکت [ ] در Regex چیست؟ (تعریف و مفهوم پایه)
در عبارات منظم (Regex)، براکتها [ ] یک ابزار اساسی برای تعریف «کلاس کاراکتر» هستند. به زبان ساده، براکت به موتور Regex میگوید: «فقط یکی از کاراکترهایی که داخل من هستند را پیدا کن». این یکی از پرکاربردترین قابلیتها برای تطبیق الگوهایی است که نیاز به انعطافپذیری دارند.
درک مفهوم «کلاس کاراکتر» (Character Class)
«کلاس کاراکتر» (Character Class) که با [ ] مشخص میشود، مجموعهای از کاراکترها است که شما میخواهید در یک موقعیت خاص در متن، یکی از آنها مطابقت پیدا کند.
فرض کنید میخواهید تمام حروف صدادار (vowels) را در یک متن انگلیسی پیدا کنید. به جای نوشتن پنج دستور جداگانه، آنها را در یک کلاس کاراکتر قرار میدهید:
[aeiou]
این الگو به موتور Regex میگوید که هر جا حرف ‘a’، ‘e’، ‘i’، ‘o’ یا ‘u’ را دید، آن را به عنوان یک تطبیق (match) در نظر بگیرد. این روش بسیار بهینهتر از جستجوی جداگانه هر کاراکتر است.
تفاوت تطبیق یک کاراکتر در مقابل مجموعهای از کاراکترها
درک تفاوت بین جستجوی یک کاراکتر ثابت و یک کلاس کاراکتر، کلیدی است.
- تطبیق کاراکتر ثابت: وقتی شما الگوی a را مینویسید، به موتور Regex میگویید: «دقیقاً و فقط حرف a را پیدا کن».
- تطبیق کلاس کاراکتر: وقتی الگوی [a] را مینویسید، میگویید: «یکی از کاراکترهای داخل این براکت را پیدا کن».
در این مثال خاص، چون فقط ‘a’ داخل براکت است، نتیجهی عملیاتی a و [a] یکسان است. اما تفاوت اصلی زمانی مشخص میشود که ما به کلاس کاراکتر، اعضای بیشتری اضافه کنیم.
چرا [abc] با abc متفاوت است؟ (تحلیل مثال)
این تفاوت، یکی از مفاهیم پایهای در Regex است که درک آن اهمیت زیادی دارد.
- الگوی abc (دنباله):
این الگو به معنای «دنباله» (Sequence) است. موتور Regex باید دقیقاً حرف ‘a’، سپس بلافاصله حرف ‘b’ و سپس بلافاصله حرف ‘c’ را پیدا کند. این الگو فقط با رشته “abc” مطابقت دارد.
- الگوی [abc] (کلاس):
این الگو به معنای «کلاس کاراکتر» است. موتور Regex باید فقط یکی از حروف داخل براکت را پیدا کند: یا ‘a’ یا ‘b’ یا ‘c’.
برای درک بهتر، به این جدول مقایسه توجه کنید:
| الگو (Pattern) | متن مورد جستجو (Text) | نتیجه (Match?) | توضیح |
| abc | “abcde” | abc | مطابقت دارد، چون دنباله “abc” پیدا شد. |
| abc | “acbde” | ندارد | مطابقت ندارد، چون ترتیب حروف رعایت نشده است. |
| [abc] | “abcde” | a | مطابقت دارد. اولین کاراکتر (‘a’) پیدا شد. |
| [abc] | “cbade” | c | مطابقت دارد. اولین کاراکتر (‘c’) پیدا شد. |
| [abc] | “xyz” | ندارد | مطابقت ندارد، چون هیچکدام از حروف a, b, c در متن نیست. |
نکته کلیدی: الگوی [abc] اگر به صورت سراسری (global) جستجو شود، سه بار در متن “abcde” مطابقت پیدا میکند (یک بار ‘a’، یک بار ‘b’ و یک بار ‘c’). در حالی که الگوی abc فقط یک بار با کل رشته “abc” مطابقت پیدا میکند.
بنابراین، براکتها ابزار انتخاب (Or) هستند، در حالی که کاراکترهای پشت سر هم، ابزار ترتیب و دنباله (And) هستند.
آموزش گام به گام استفاده از براکت برای تطبیق مجموعه کاراکترها
استفاده از براکتها یا همان «کلاس کاراکتر» (Character Class) در Regex بسیار مستقیم و کاربردی است. این ابزار به شما اجازه میدهد تا به جای جستجوی یک کاراکتر ثابت، مجموعهای از گزینههای ممکن را برای یک موقعیت خاص تعریف کنید. در این بخش، روشهای اصلی استفاده از [ ] را گام به گام بررسی میکنیم.
تطبیق کاراکترهای خاص: [aeiou]
سادهترین و پایهایترین کاربرد براکت، لیست کردن مستقیم تمام کاراکترهایی است که میخواهید مطابقت داده شوند.
الگو: [aeiou]
تحلیل:
این الگو به موتور Regex دستور میدهد که در متن جستجو کند و هر کاراکتری را که یکی از حروف ‘a’، ‘e’، ‘i’، ‘o’ یا ‘u’ باشد، پیدا کند.
- نکته مهم: ترتیب نوشتن کاراکترها در داخل براکت هیچ اهمیتی ندارد. الگوی [eiaou] دقیقاً همان کار [aeiou] را انجام میدهد.
ترکیب حروف و اعداد: [a-z0-9]
نوشتن تمام حروف الفبا یا تمام اعداد به صورت دستی (مانند [abcdef…z]) ناکارآمد و غیرعملی است. برای حل این مشکل، Regex از مفهوم «محدوده» (Range) پشتیبانی میکند که با استفاده از کاراکتر خط تیره (-) تعریف میشود.
مثالهای محدوده:
- [a-z]: این الگو هر یک حرف کوچک انگلیسی (از ‘a’ تا ‘z’) را پیدا میکند.
- [A-Z]: این الگو هر یک حرف بزرگ انگلیسی (از ‘A’ تا ‘Z’) را پیدا میکند.
- [0-9]: این الگو هر یک رقم عددی (از ‘0’ تا ‘9’) را پیدا میکند.
شما میتوانید این محدودهها و کاراکترهای خاص را در یک براکت واحد ترکیب کنید.
الگوی ترکیبی: [a-z0-9]
تحلیل:
این الگو به موتور Regex میگوید: «هر کاراکتری که یا یک حرف کوچک انگلیسی باشد (از a تا z) یا یک رقم عددی باشد (از 0 تا 9) را پیدا کن».
- این الگو با ‘a’، ‘b’، ‘5’ و ‘9’ مطابقت دارد.
- این الگو با ‘A’، ‘B’، ‘!’ یا ‘@’ مطابقت ندارد.
حساسیت به حروف بزرگ و کوچک (Case-Sensitivity) و استفاده از فلگ i
به طور پیشفرض، عبارات منظم (Regex) به بزرگی و کوچکی حروف حساس (Case-Sensitive) هستند.
این به آن معناست که الگوی [a-z] فقط حروف کوچک را پیدا میکند و ‘A’ یا ‘B’ را نادیده میگیرد.
برای حل این مشکل دو راه اصلی وجود دارد:
۱. تعریف هر دو محدوده در براکت:
شما میتوانید هر دو محدوده حروف بزرگ و کوچک را مستقیماً در کلاس کاراکتر بنویسید:
[a-zA-Z]
این الگو هم ‘a’ و هم ‘A’ (و تمام حروف دیگر) را پیدا میکند.
۲. استفاده از فلگ i (راهکار بهینهتر):
فلگها (Flags)، تنظیماتی هستند که رفتار کلی موتور Regex را تغییر میدهند. فلگ i (مخفف case-insensitive) به موتور دستور میدهد که کل الگو را بدون توجه به بزرگی یا کوچکی حروف بررسی کند.
مقایسه:
- الگوی حساس: /[a-z]/ (فقط ‘a’, ‘b’, ‘c’ و…)
- الگوی غیرحساس: /[a-z]/i (هم ‘a’, ‘b’, ‘c’ و هم ‘A’, ‘B’, ‘C’ و…)
استفاده از فلگ i معمولاً الگو را تمیزتر و خواناتر نگه میدارد و دیگر نیازی به نوشتن [a-zA-Z] برای تطبیق حروف الفبا نیست.
تطبیق بازهها (Ranges) با استفاده از خط تیره (-)
در عبارات منظم، نوشتن تکتک کاراکترها در یک کلاس (مثل [0123456789]) منطقی و بهینه نیست. برای حل این مشکل، از کاراکتر خط تیره (-) استفاده میکنیم.
خط تیره وقتی داخل براکت [ ] قرار میگیرد، به عنوان یک «متاکاراکتر» (Metacharacter) عمل میکند. معنای آن این است: «تمام کاراکترهایی که بین این دو نقطه (بر اساس ترتیب استاندارد کاراکترها مانند ASCII) قرار دارند را در نظر بگیر».
این روشی بهینه برای تعریف مجموعههای بزرگ و ترتیبی است.
بازه حروف: [a-z] و [A-Z]
اینها پایهایترین بازههای مور استفاده در Regex هستند:
- [a-z]: این الگو دقیقاً یک کاراکتر از حروف کوچک انگلیسی (از ‘a’ تا ‘z’) را تطبیق میدهد.
- [A-Z]: این الگو دقیقاً یک کاراکتر از حروف بزرگ انگلیسی (از ‘A’ تا ‘Z’) را تطبیق میدهد.
باید تأکید کنم که این دو بازه، به دلیل حساسیت پیشفرض Regex به بزرگی و کوچکی حروف (Case-Sensitivity)، کاملاً مجزا هستند. الگوی [a-z] حرف ‘A’ را پیدا نمیکند.
بازه اعداد: [0-9] (معادل \d)
برای تطبیق یک رقم عددی (از ‘0’ تا ‘9’)، از بازه [0-9] استفاده میکنیم. این یکی از پرکاربردترین بازهها است، مثلاً برای پیدا کردن شماره تلفن یا اعتبارسنجی کدهای پستی.
به دلیل کاربرد بسیار زیاد، Regex یک «کلاس کاراکتر از پیشتعریفشده» (Predefined Character Class) برای آن در نظر گرفته است: \d (مخفف digit).
مقایسه [0-9] و \d
| الگو (Pattern) | معنی | مثال تطبیق |
| [0-9] | یک رقم از 0 تا 9 | “User7“ |
| \d | یک رقم (معادل دقیق [0-9]) | “User7“ |
در بیشتر موتورهای Regex مدرن، \d و [0-9] عملکرد یکسانی دارند.
ترکیب بازهها: [A-Za-z0-9_] (معادل \w)
قدرت اصلی براکتها در قابلیت ترکیب آنهاست. شما میتوانید بازههای مختلف و کاراکترهای تکی را به سادگی در کنار هم قرار دهید.
الگوی [a-zA-Z0-9_] یک ترکیب بسیار رایج است. این الگو موارد زیر را تطبیق میدهد:
- a-z (تمام حروف کوچک)
- A-Z (تمام حروف بزرگ)
- 0-9 (تمام اعداد)
- _ (کاراکتر آندرلاین)
این ترکیب آنقدر پرکاربرد است که Regex برای آن نیز یک میانبر (Shorthand) تعریف کرده است: \w (مخفف word character).
بنابراین، \w به معنای «هر حرف الفبا (بزرگ یا کوچک)، هر عدد، یا کاراکتر آندرلاین» است.
اشتباهات رایج در تعریف بازه (مثال: [z-a])
یک اشتباه رایج، تعریف بازه به صورت معکوس یا اشتباه است.
الگوی اشتباه: [z-a]
تحلیل:
موتور Regex انتظار دارد که نقطه شروع (سمت چپ خط تیره) در جدول ترتیب کاراکترها (مانند ASCII) قبل از نقطه پایان (سمت راست) باشد.
وقتی الگوی [z-a] را مینویسید، Regex نمیتواند بازهای از ‘z’ به ‘a’ را بسازد. این الگو در بیشتر موتورهای Regex (مانند PCRE، جاوااسکریپت، پایتون) کار نمیکند و معمولاً یا خطا میدهد یا هیچ کاراکتری را تطبیق نمیدهد.
نکته کلیدی: همیشه مطمئن شوید که بازهها را به ترتیب صعودی استاندارد (مانند a-z یا 0-9) تعریف میکنید.
نفی کردن مجموعه با ^ (Negated Character Classes)
تا اینجا دیدیم که براکتها [ ] برای «انتخاب» (Inclusion) به کار میروند؛ یعنی «یکی از این موارد». اما گاهی نیاز داریم دقیقاً برعکس عمل کنیم: «هر کاراکتری به جز این موارد».
در عبارات منظم (Regex)، این قابلیت با استفاده از کاراکتر ^ (هشت یا Caret) پیادهسازی میشود.
وقتی ^ بلافاصله بعد از براکت باز [ قرار میگیرد، معنای کل آن «کلاس کاراکتر» را معکوس (نفی) میکند. به این ساختار «کلاس کاراکتر نفی شده» (Negated Character Class) گفته میشود.
کاربرد [^…] برای تطبیق «هر کاراکتری به جز»
ساختار [^…] بسیار مستقیم عمل میکند. این الگو به موتور Regex میگوید: «هر کاراکتر تکی را پیدا کن، به شرطی که آن کاراکتر در لیستی که جلوی ^ آمده است، وجود نداشته باشد.»
این ابزار برای فیلتر کردن کاراکترهای ناخواسته بسیار قدرتمند است.
مثال عملی: تطبیق هر کاراکتر به جز حروف صدادار [^aeiou]
بیایید مثال حروف صدادار را که قبلاً بررسی کردیم، معکوس کنیم:
- الگوی [aeiou]:
- معنی: فقط حروف صدادار (‘a’, ‘e’, ‘i’, ‘o’, ‘u’) را پیدا کن.
- الگوی [^aeiou]:
- معنی: دقیقاً برعکس؛ هر کاراکتر تکی را پیدا کن که ‘a’, ‘e’, ‘i’, ‘o’, ‘u’ نباشد.
این الگو شامل حروف بیصدا (مانند ‘b’, ‘c’, ‘d’)، اعداد (مانند ‘1’, ‘2’)، کاراکترهای خاص (مانند ‘!’) و حتی فاصله (Space) میشود.
مقایسه در عمل:
| الگو (Pattern) | متن مورد جستجو (Text) | تطبیقها (Matches) |
| [aeiou] | “hello world 1!” | ‘e’, ‘o’, ‘o’ |
| [^aeiou] | “hello world 1!” | ‘h’, ‘l’, ‘l’, ‘ ‘, ‘w’, ‘r’, ‘l’, ‘d’, ‘ ‘, ‘1’, ‘!’ |
تفاوت ^ در داخل براکت و ^ در ابتدای عبارت Regex
این یکی از مهمترین مفاهیمی است که افراد تازهکار در Regex باید به آن مسلط شوند. جایگاه کاراکتر ^ معنای آن را کاملاً تغییر میدهد.
^ یک «متاکاراکتر» (Metacharacter) با دو کاربرد کاملاً متفاوت است:
۱. ^ در ابتدای عبارت (به عنوان Anchor):
- وقتی ^ خارج از براکت و در ابتدای کل الگو میآید (مثال: ^Hello)، به معنای «لنگر شروع رشته» (Start of String Anchor) است.
- این الگو به موتور میگوید: «تطبیق باید فقط و فقط از ابتدای متن شروع شود».
۲. ^ در داخل براکت (به عنوان Negation):
- وقتی ^ بلافاصله بعد از براکت باز [ قرار میگیرد (مثال: [^abc])، به معنای «نفی کردن» (Negation) است.
- این الگو میگوید: «هر کاراکتر تکی به جز ‘a’, ‘b’, ‘c’».
جدول مقایسه کاربرد ^:
| جایگاه ^ | الگو (مثال) | معنای الگو |
| خارج از براکت (در ابتدا) | ^Start | تطبیق کلمه “Start” فقط اگر در ابتدای رشته باشد. |
| داخل براکت (در ابتدا) | [^abc] | تطبیق یک کاراکتر که ‘a’ یا ‘b’ یا ‘c’ نباشد. |
نکته مهم: اگر ^ داخل براکت باشد، اما اولین کاراکتر نباشد (مثلاً [a^bc])، معنای خاصی ندارد و فقط به عنوان خودِ کاراکترِ ^ (هشت) در نظر گرفته میشود. در این مثال، الگو با ‘a’ یا ‘^’ یا ‘b’ مطابقت دارد.
کار با کاراکترهای ویژه (Metacharacters) در داخل براکت
چرا کاراکترهایی مانند .، *، + و ? معنای خود را در داخل [ ] از دست میدهند؟
دلیل این موضوع، منطقِ «کلاس کاراکتر» است. وظیفه براکت [ ] این است که فقط یک «مجموعه از کاراکترهای مجاز» را برای یک موقعیت تعریف کند.
در این محیط، موتور Regex به دنبال تعریف دنباله (sequence) یا تکرار (quantifier) نیست؛ فقط میپرسد: «کدام کاراکترها مجاز هستند؟».
بنابراین، کاراکترهایی مثل . (نقطه)، * (ستاره)، + (بعلاوه) و ? (علامت سوال)، که در خارج از براکت معنای خاصی (مانند «هر کاراکتری» یا «صفر یا چند بار») دارند، در داخل براکت [ ] قدرت خود را از دست میدهند و به کاراکترهای عادی (Literal) تبدیل میشوند.
مقایسه عملی:
- الگوی a* (خارج از براکت):
- معنی: «صفر یا چند بار» تکرار حرف ‘a’.
- تطبیق: “”, “a”, “aa”, “aaa”
- الگوی [a*] (داخل براکت):
- معنی: «یا حرف ‘a’ یا کاراکتر ستاره (*)».
- تطبیق: “a” یا “*”
چگونه کاراکترهای ویژه خود براکت ]، خط تیره – و ^ را تطبیق دهیم؟
همانطور که گفتیم، بیشتر متاکاراکترها در داخل براکت عادی میشوند. اما چهار کاراکتر در داخل براکت [ ] همچنان «ویژه» محسوب میشوند و باید مدیریت شوند:
- ] (براکت بسته): چون به معنای پایان کلاس کاراکتر است.
- – (خط تیره): چون برای تعریف بازه (Range) استفاده میشود.
- ^ (هشت): چون اگر در ابتدا بیاید، کلاس را نفی (Negate) میکند.
- \ (بکاسلش): چون خودِ آن، کاراکتر گریز (Escape) است.
روش تطبیق لغوی (Literal) این موارد:
- برای ]: باید آن را با بکاسلش گریز دهید (\[) یا آن را اولین کاراکتر در براکت قرار دهید ([]abc]).
- برای -: یا آن را گریز دهید (\-) یا آن را در ابتدا یا انتهای کلاس قرار دهید (در بخش بعد توضیح داده میشود).
- برای ^: یا آن را گریز دهید (\^) یا آن را در هر جایی به جز ابتدای کلاس قرار دهید (مثال: [a^b] یعنی ‘a’ یا ‘^’ یا ‘b’).
- برای \: باید آن را با خودش گریز دهید (\\).
موقعیت خط تیره (-) برای تطبیق لغوی (Literal)
کاراکتر خط تیره (-) در داخل براکت برای تعریف بازه (مثل [0-9]) استفاده میشود. اگر بخواهیم خودِ کاراکترِ خط تیره را تطبیق دهیم (مثلاً در عبارتی مثل “user-name”)، باید آن را طوری قرار دهیم که معنای «بازه» ندهد.
دو راه امن برای این کار وجود دارد:
۱. قرار دادن در ابتدا یا انتهای کلاس (روش رایج):
اگر – اولین یا آخرین کاراکتر در براکت باشد، موتور Regex آن را به عنوان یک کاراکتر لغوی در نظر میگیرد، نه تعریفکننده بازه.
- الگو: [-az] (یعنی ‘–’ یا ‘a’ یا ‘z’)
- الگو: [az-] (یعنی ‘a’ یا ‘z’ یا ‘–’)
۲. گریز با بکاسلش (روش واضح):
میتوانید به سادگی آن را با \ گریز دهید تا معنای ویژهاش خنثی شود.
- الگو: [a\-z] (یعنی ‘a’ یا ‘–’ یا ‘z’)
هر دو روش صحیح هستند، اما قرار دادن آن در ابتدا یا انتها معمولاً خواناتر است.
استفاده از بکاسلش \ در داخل براکتها
بکاسلش \ در داخل براکتها [ ] دو کاربرد اصلی و مهم دارد:
۱. گریز دادن (Escaping) متاکاراکترهای داخل براکت:
همانطور که دیدیم، برای خنثی کردن معنای ویژه ], ^, – و خودِ \ (برای تطبیق لغوی بکاسلش)، از \ استفاده میکنیم.
- مثال: [\\^] (یعنی کاراکتر بکاسلش \ یا کاراکتر هشت ^).
۲. استفاده از کلاسهای کاراکتر از پیشتعریفشده:
شما میتوانید میانبرهایی مثل \d (اعداد)، \w (حروف و اعداد) و \s (فواصل) را در داخل براکتها به کار ببرید تا با مجموعههای دیگر ترکیب شوند.
- مثال: [\dabc] به معنای «هر رقم عددی (0-9) یا ‘a’ یا ‘b’ یا ‘c’» است.
- این قابلیت برای ترکیب مجموعهها بسیار مفید است، مثلا [\w\-] (هر حرف، عدد، آندرلاین، یا خط تیره).
مثالهای پیشرفته و کاربردی از کلاسهای کاراکتر
کلاسهای کاراکتر [ ] فقط برای تطبیق حروف الفبا یا اعداد نیستند. قدرت اصلی آنها زمانی مشخص میشود که برای حل مسائل واقعی و اعتبارسنجی دادهها از آنها استفاده کنیم. در ادامه، سه سناریوی عملی را بررسی میکنیم.
اعتبارسنجی یک پسورد ساده [a-zA-Z0-9!@#]
فرض کنید قانونی در سیستم خود دارید که میگوید پسورد باید فقط شامل حروف انگلیسی (بزرگ و کوچک)، اعداد و کاراکترهای خاص !@# باشد.
الگو: [a-zA-Z0-9!@#]
تحلیل:
این کلاس کاراکتر، تمام کاراکترهای مجاز را در یک مجموعه تعریف میکند:
- a-z: حروف کوچک
- A-Z: حروف بزرگ
- 0-9: اعداد
- !@#: کاراکترهای خاص مجاز (اینها در داخل براکت معنای ویژهای ندارند)
نحوه استفاده:
این الگو به تنهایی یک کاراکتر را بررسی میکند. در عمل، ما معمولاً آن را با «سورها» (Quantifiers) و «لنگرها» (Anchors) ترکیب میکنیم.
- الگوی کاربردی: ^[a-zA-Z0-9!@#]{8,}$
- معنی این الگو:
- ^: از ابتدای رشته شروع کن.
- [a-zA-Z0-9!@#]: فقط از کاراکترهای مجاز ما استفاده کن.
- {8,}: این کاراکترها باید حداقل ۸ بار یا بیشتر تکرار شوند.
- $: تا انتهای رشته ادامه بده.
این الگو تضمین میکند که کل رشته (پسورد) حداقل ۸ کاراکتر طول دارد و هیچ کاراکتر غیرمجازی (مثل $ یا %) در آن وجود ندارد.
پیدا کردن تمام هدرهای HTML (مثال: [hH][1-6])
سناریوی رایج دیگر، جستجو در کد HTML است. فرض کنید میخواهیم تمام تگهای هدر (از <h1> تا <h6>) را پیدا کنیم، بدون اینکه به بزرگی یا کوچکی حرف ‘h’ حساس باشیم.
الگو: [hH][1-6]
تحلیل:
این الگو از دو کلاس کاراکتر پشت سر هم تشکیل شده است:
- [hH]: کلاس کاراکتر اول. به موتور میگوید «یا ‘h’ کوچک یا ‘H’ بزرگ».
- [1-6]: کلاس کاراکتر دوم. به موتور میگوید «یا ‘1’ یا ‘2’ یا ‘3’ یا ‘4’ یا ‘5’ یا ‘6’».
وقتی این دو پشت سر هم میآیند، یک «دنباله» (Sequence) میسازند. موتور Regex ابتدا یک کاراکتر مطابق با کلاس اول (h یا H) و بلافاصله پس از آن، یک کاراکتر مطابق با کلاس دوم (1 تا 6) را جستجو میکند.
این الگو مواردی مانند “h1”, “H1”, “h2”, “H6” را تطبیق میدهد، اما “h7” یا “h” (به تنهایی) را تطبیق نمیدهد.
حذف کاراکترهای نگارشی خاص از متن
یکی از کاربردهای مهم Regex، پاکسازی و آمادهسازی متن (Text Sanitization) است. فرض کنید میخواهیم تمام کاراکترهای نگارشی رایج (مانند نقطه، ویرگول، علامت سوال و…) را از یک متن حذف کنیم.
الگو: [.,!?;:'”]
تحلیل:
این یک کلاس کاراکتر ساده است که تمام کاراکترهای ناخواسته را لیست میکند.
- چگونه کار میکند؟ شما این الگو را در یک تابع «جستجو و جایگزینی» (Search & Replace) استفاده میکنید. به موتور Regex میگویید هر کاراکتری که با این الگو مطابقت داشت را با یک «رشته خالی» (“”) جایگزین کند.
مثال:
- متن اصلی: “سلام، حالت چطور است؟ من خوبم.”
- پس از اعمال الگو: “سلام حالت چطور است من خوبم”
روش معکوس (بسیار قدرتمند):
گاهی اوقات، شما میخواهید برعکس عمل کنید: یعنی «هر چیزی به جز حروف، اعداد و فاصله» را حذف کنید. در این حالت، از «کلاس نفی شده» (Negated Class) استفاده میکنیم:
- الگو: [^a-zA-Z0-9\s] (اگر فارسی هم مدنظر باشد: [^a-zA-Z0-9\sآ-ی])
- معنی: هر کاراکتری را پیدا کن که (^) حرف انگلیسی، عدد یا فاصله (\s) نباشد.
- این الگو تمام . و ، و ؟ و… را به صورت خودکار پیدا میکند تا حذف شوند.
چگونه خودِ کاراکترهای براکت [ و ] را تطبیق دهیم؟
کاراکترهای براکت [ و ] ستون فقرات «کلاسهای کاراکتر» در Regex هستند، بنابراین برای تطبیق خودِ این کاراکترها (به عنوان کاراکتر لغوی یا Literal) باید دقت به خرج داد. روش کار بسته به اینکه در داخل یک کلاس کاراکتر دیگر باشیم یا خارج از آن، متفاوت است.
فرار (Escape) کردن براکتها در خارج از کلاس کاراکتر:
$$ و $$
وقتی در جریان عادی یک عبارت Regex (خارج از [ ]) هستیم، براکت باز [ یک متاکاراکتر ویژه است که معنای «شروع کلاس کاراکتر» را میدهد.
برای اینکه به موتور Regex بگوییم منظور ما خودِ کاراکتر براکت باز است و نه شروع یک کلاس، باید آن را با بکاسلش (\) فرار (Escape) دهیم.
- الگو: \[
- معنی: کاراکتر لغوی براکت باز ([) را پیدا کن.
اگرچه در بیشتر موتورهای Regex مدرن، براکت بسته ] در خارج از کلاس، کاراکتر خاصی محسوب نمیشود (مگر اینکه براکت بازی قبل از آن باز شده باشد)، اما بهترین و امنترین روش این است که آن را هم Escape کنیم:
- الگو: \]
- معنی: کاراکتر لغوی براکت بسته (]) را پیدا کن.
مثال: برای پیدا کردن دقیق عبارت [Error] در یک متن:
- الگوی صحیح: \[Error\]
تطبیق براکت باز [ در داخل یک کلاس کاراکتر
رفتار [ در داخل یک کلاس کاراکتر دیگر، جالب است.
وقتی شما یک کلاس کاراکتر را باز میکنید (مثلاً با [)، موتور Regex دیگر انتظار یک براکت باز دیگر را ندارد. بنابراین، در بیشتر موتورهای Regex، قرار دادن [ در داخل یک کلاس [ ] نیاز به Escape کردن ندارد و به عنوان یک کاراکتر عادی شناخته میشود.
- الگو: [abc[]
- معنی: یکی از کاراکترهای ‘a’، ‘b’، ‘c’ یا براکت باز [ را پیدا کن.
روش امن:
با این حال، برای اطمینان صددرصد و خوانایی بیشتر، میتوانید آن را در داخل کلاس هم Escape کنید. این کار هیچ ضرری ندارد و در تمام موتورها به درستی کار میکند.
- الگوی امنتر: [abc\[] (معنی یکسان با قبلی)
تطبیق براکت بسته ] در داخل یک کلاس کاراکتر
براکت بسته ] در داخل یک کلاس کاراکتر، بسیار حساس است، چون معنای «پایان کلاس» را میدهد.
اگر ] را به صورت عادی داخل کلاس بنویسید (مثلاً [abc]])، موتور Regex دچار خطا میشود. کلاس در [abc] بسته میشود و ] دوم یک کاراکتر اضافی و بیمعنی در الگو تلقی میگردد.
برای تطبیق لغوی ] در داخل یک کلاس، دو راه وجود دارد:
۱. فرار (Escape) کردن آن (روش استاندارد):
سادهترین راه، گریز دادن آن با بکاسلش است.
- الگو: [abc\]]
- معنی: یکی از کاراکترهای ‘a’، ‘b’، ‘c’ یا براکت بسته ] را پیدا کن.
۲. قرار دادن آن به عنوان اولین کاراکتر:
یک ترفند در Regex وجود دارد: اگر ] اولین کاراکتر بعد از براکت باز (یا اولین کاراکتر بعد از هشت نفی ^) باشد، موتور آن را به عنوان یک کاراکتر لغوی میشناسد، زیرا در آن موقعیت نمیتواند به معنای «پایان کلاس» باشد.
- الگو: []abc]
- معنی: یکی از کاراکترهای ‘]’، ‘a’، ‘b’ یا ‘c’ را پیدا کن.
- مثال نفی شده: [^]abc] (هر کاراکتری به جز ‘]’، ‘a’، ‘b’ یا ‘c’)
این روش دوم کمی گیجکننده به نظر میرسد، اما کاملاً معتبر است. با این حال، استفاده از بکاسلش (\[ و \]) همیشه واضحترین و امنترین راه باقی میماند.
خلاصهی تقلب (Cheat Sheet) براکتها در Regex
کلاسهای کاراکتر (براکتها) یکی از پرکاربردترین بخشهای عبارات منظم هستند. این خلاصهی تقلب (Cheat Sheet) به شما کمک میکند تا به سرعت به الGOهای اصلی دسترسی داشته باشید. این بخش برای مرور سریع و استفاده عملی طراحی شده است.
جدول سریع دستورات اصلی (تطبیق، بازه، نفی)
در جدول زیر، دستورات پایهای که میتوانید در داخل براکتها [ ] استفاده کنید، خلاصه شدهاند:
| الگو (Pattern) | توضیح |
| [abc] | تطبیق یکی از کاراکترهای ‘a’ یا ‘b’ یا ‘c’. |
| [a-z] | تطبیق یکی از کاراکترهای حروف کوچک انگلیسی (از a تا z). |
| [A-Z] | تطبیق یکی از کاراکترهای حروف بزرگ انگلیسی (از A تا Z). |
| [0-9] | تطبیق یکی از ارقام (از 0 تا 9). |
| [a-zA-Z] | تطبیق یکی از حروف انگلیسی (کوچک یا بزرگ). |
| [^abc] | نفی کردن: تطبیق یکی از کاراکترها که ‘a’، ‘b’ یا ‘c’ نباشد. |
| [^a-z] | نفی کردن: تطبیق یکی از کاراکترها که حرف کوچک انگلیسی نباشد. |
کلاسهای کاراکتر از پیش تعریف شده (\d, \w, \s) و معادل براکت آنها
برای راحتی و خوانایی بیشتر الگوها، Regex میانبرهایی (Shorthands) را ارائه میدهد که معادل کلاسهای کاراکتر بسیار رایج هستند. مهمترین آنها عبارتند از:
- \d (Digit): برای اعداد
- \w (Word): برای حروف، اعداد و آندرلاین
- \s (Whitespace): برای فضاها، تبها و خطوط جدید
در جدول زیر، این میانبرها و معادل دقیق آنها در براکت، و همچنین حالت نفیشده (حرف بزرگ) آنها را مشاهده میکنید:
| میانبر (Shorthand) | معادل براکت (Bracket Equivalent) | توضیح |
| \d | [0-9] | هر رقم عددی. |
| \D | [^0-9] | هر کاراکتری که رقم نباشد. |
| \w | [a-zA-Z0-9_] | هر کاراکتر کلمه (حروف انگلیسی، اعداد و آندرلاین). |
| \W | [^a-zA-Z0-9_] | هر کاراکتری که کاراکتر کلمه نباشد (مثل @, !, ,). |
| \s | [ \t\r\n\f\v] | هر کاراکتر فضای خالی (شامل فاصله، تب، خط جدید و…). |
| \S | [^ \t\r\n\f\v] | هر کاراکتری که فضای خالی نباشد. |
جمعبندی
استفاده از براکتها [ ] یا همان «کلاسهای کاراکتر»، یکی از مهارتهای اصلی در کار با Regex است. همانطور که در این مقاله بررسی کردیم، این ابزار به شما امکان میدهد تا الگوهای پیچیدهای را به شکلی خوانا و بهینه پیادهسازی کنید.
تسلط بر تعریف بازهها (a-z)، نفی کردن مجموعهها ([^…]) و نحوه رفتار متاکاراکترها در داخل براکت (مانند .، * یا -)، به شما کمک میکند تا کنترل کاملی بر روی تطبیق کاراکترها در اعتبارسنجی فرمها، پاکسازی دادهها و جستجوهای پیشرفته داشته باشید. این قابلیت، پایه و اساس بسیاری از الگوهای پیچیدهتر در عبارات منظم است.