عبارتهای باقاعده (RegExp)
ساخت الگو، Flagها، Character Class، Quantifier، گروهها و Capturing، Lookahead و Lookbehind، Anchor، جستوجو و جایگزینی و اعتبارسنجی با RegExp.
RegExp چیست؟
عبارت باقاعده (Regular Expression) زبانی برای توصیف الگوی متن است — جستوجو، تطبیق و دستکاری رشته:
// دو روش ساخت:
const re1 = /hello/gi; // Literal — سادهتر
const re2 = new RegExp("hello", "gi"); // Constructor — برای الگوی پویا
const text = "Hello World, hello JS!";
console.log(text.match(re1)); // ["Hello", "hello"]
Flagها — پرچمها
| Flag | نام | کار |
|---|---|---|
g | global | همه تطبیقها (نه فقط اولی) |
i | ignoreCase | بیتوجه به بزرگی/کوچکی |
m | multiline | ^ و $ برای هر خط |
s | dotAll | . شامل newline میشود |
u | unicode | پشتیبانی کامل یونیکد |
y | sticky | تطبیق از موقعیت دقیق |
console.log("JS js Js".match(/js/gi)); // ["JS", "js", "Js"]
console.log("a\nb".match(/^b/m)); // تطبیق — با m
Character Class — کلاس کاراکترها
const text = "Phone: 0912-345-6789, Code: ABC-123";
// \d رقم — \D غیر رقم:
console.log(text.match(/\d+/g)); // ["0912", "345", "6789"]
// \w حرف/رقم/_ — \W برعکس:
console.log("a1_!".match(/\w/g)); // ["a", "1", "_"]
// \s فاصله — \S غیر فاصله:
console.log("a b\tc".match(/\s/g)); // [" ", "\t"]
// مجموعه دلخواه [abc] — هر کدام:
console.log("cat bat hat".match(/[cb]at/g)); // ["cat", "bat"]
// بازه [a-z] و [0-9]:
console.log("a1B2c3".match(/[a-c0-3]/g)); // ["a", "1", "c", "3"]
// نفی [^abc] — هر چیزی جز:
console.log("cat dog".match(/[^a ]/g)); // ["c", "t", "d", "o", "g"]
Quantifier — کمیتسنجها
// + یک یا بیشتر، * صفر یا بیشتر، ? اختیاری:
console.log("color colour".match(/colou?r/g)); // ["color", "colour"]
// {n} دقیقاً n بار:
console.log("aa aaa aaaa".match(/a{3}/g)); // ["aaa", "aaa"]
// {n,} حداقل n، {n,m} بین n و m:
console.log("1 22 333 4444".match(/\d{2,3}/g)); // ["22", "333", "444"]
// حریص در برابر تنبل (greedy vs lazy):
const html = "<tag>اول</tag> <tag>دوم</tag>";
console.log(html.match(/<tag>.*<\/tag>/)); // کل متن — حریص!
console.log(html.match(/<tag>.*?<\/tag>/)); // فقط اولی — تنبل
Group — گروهبندی
// گروه (...) — چند الگو را یکجا:
console.log("abcabc".match(/(abc)+/)); // "abcabc"
// Capturing Group — گرفتن بخشها:
const dateStr = "2025-01-15";
const match = dateStr.match(/(\d{4})-(\d{2})-(\d{2})/);
console.log(match[1]); // 2025 — سال
console.log(match[2]); // 01 — ماه
console.log(match[3]); // 15 — روز
// Named Group — نامدار (م readable):
const named = dateStr.match(/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/);
console.log(named.groups.year); // 2025
console.log(named.groups.month); // 01
Non-Capturing و Backreference
// (?:...) — گروه بدون ذخیره:
console.log("2025-01-15".match(/(?:\d{4})-(\d{2})-(\d{2})/).length); // 3 کل+۲ گروه
// \1 — ارجاع به گروه قبلی:
console.log("abab cdcd xy".match(/(\w\w)\1/g)); // ["abab", "cdcd"] — تکراریها!
Lookahead — پیشنگری
شرط بعد از موقعیت فعلی بدون مصرف کاراکتر:
// (?=...) — مثبت: باید باشد:
console.log("a1b2c3".match(/\d(?=[a-z])/g)); // ["1", "2"] — رقم قبل از حرف
// (?!...) — منفی: نباشد:
console.log("100 200 3000".match(/\d{3}(?! )/g)); // ["300"] — ۳رقمی که بعدش فاصله نیست
console.log("free free2".match(/free(?!2)/g)); // ["free"] — اولی
Lookbehind — پسنگری
شرط قبل از موقعیت فعلی:
// (?<=...) — مثبت:
console.log("$100 €200".match(/(?<=$)\d+/g)); // ["100"] — بعد از $
// (?<!...) — منفی:
console.log("a1 b2 c3".match(/(?<![ab])\d/g)); // ["3"] — رقم که قبلش a یا b نیست
Anchor — لنگرها
// ^ شروع رشته:
console.log(/^Hello/.test("Hello World")); // true
console.log(/^World/.test("Hello World")); // false
// $ پایان رشته:
console.log(/World$/.test("Hello World")); // true
// \b مرز کلمه:
console.log("cat catalog".match(/\bcat\b/g)); // ["cat"] — فقط کلمه کامل
// اعتبارسنجی کامل رشته:
const isValid = /^\d{11}$/.test("09123456789");
console.log(isValid); // true — دقیقاً ۱۱ رقم
متدهای رشته با RegExp
const text = "ساعت 10 و 20 دقیقه است";
// test — آیا تطبیق دارد:
console.log(/\d+/.test(text)); // true
// exec — اولین تطبیق با جزئیات:
console.log(/\d+/.exec(text)); // ["10", index: 6, ...]
// match — همه یا اولی:
console.log(text.match(/\d+/g)); // ["10", "20"]
// matchAll — همه با گروهها (iterator):
for (const m of text.matchAll(/(\d+)/g)) {
console.log(m[1]); // 10، 20
}
// search — ایندکس اولین:
console.log(text.search(/\d+/)); // 6
// replace — جایگزینی:
console.log(text.replace(/\d+/g, "X")); // ساعت X و X دقیقه است
// replace با callback:
console.log("10 20 30".replace(/\d+/g, d => d * 2)); // 20 40 60
// split با الگو:
console.log("a1b2c3".split(/\d/)); // ["a", "b", "c"]
ویژگیهای شیء RegExp
const re = /(\d{2})\/(\d{2})/g;
console.log(re.source); // "(\d{2})/(\d{2})" — بدون اسلش
console.log(re.flags); // "g"
console.log(re.global); // true
console.log(re.ignoreCase); // false
console.log(re.lastIndex); // 0 — موقعیت فعلی (با g)
// lastIndex در عمل:
const re2 = /a/g;
const str = "aba";
console.log(re2.test(str)); // true — lastIndex: 1
console.log(re2.test(str)); // true — lastIndex: 3
console.log(re2.test(str)); // false — از 3 به بعد نیست
اعتبارسنجیهای کاربردی
const validators = {
// موبایل ایران:
phone: /^09\d{9}$/,
// ایمیل (ساده):
email: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
// کد ملی (۱۰ رقم):
nationalId: /^\d{10}$/,
// رمز: حداقل ۸، حرف+رقم:
password: /^(?=.*[a-zA-Z])(?=.*\d).{8,}$/,
// URL:
url: /^https?:\/\/[^\s]+$/,
// فقط حروف فارسی:
persian: /^[\u0600-\u06FF\s]+$/
};
console.log(validators.phone.test("09123456789")); // true
console.log(validators.email.test("test@site.com")); // true
console.log(validators.password.test("abc12345")); // true
console.log(validators.persian.test("سلام دنیا")); // true
جمعبندی
| الگو | معنی |
|---|---|
\d \w \s | رقم، حرف، فاصله |
+ * ? | ۱+، ۰+، ۰ یا ۱ |
(...) | گروه Capturing |
(?<name>...) | گروه نامدار |
(?=...) (?!...) | Lookahead مثبت/منفی |
^ $ \b | شروع، پایان، مرز کلمه |
این مبحث بخشی از دوره آموزش کامل جاوا اسکریپت است.