عبارات باقاعده (Regular expressions) الگوهایی هستند که روشی قدرتمند برای جستجو و جایگزینی در متن ارائه می دهند.
در جاوااسکریپت، آنها از طریق شیء RegExp استفاده می شوند و همچنین به خوبی با متد های رشته ها ادغام می شوند.
عبارات باقاعده (Regular Expressions)
عبارت باقاعده (همچنین “regexp”، یا فقط “reg”) از یک الگو(pattern) و پرچم های(flags) اختیاری تشکیل می شوند.
دو روش وجود دارد که می توان از آنها برای ایجاد یک شیء عبارت باقاعده استفاده کرد.
سینتکس “طولانی”:
regexp = new RegExp("pattern(الگو)", "flags(پرچم)");
و سینتکس “کوتاه” نیز، استفاده از اسلش "/"
می باشد.
regexp = /pattern/; // بدون پرچم
regexp = /pattern/gmi; // (به زودی گفته میشود) i، m، g با پرچم
اسلش های /.../
به جاوااسکریپت می گوید که ما در حال ایجاد یک عبارت باقاعده هستیم. آنها همان نقش کوتیشن(') را برای رشته ها بازی می کنند.
در هر دو مورد، regexp
به یک نمونه از کلاس درونساختRegExp
تبدیل می شود.
تفاوت اصلی بین این دو سینتکس این است که الگو با استفاده از اسلشهای /.../
، اجازه درج عبارات را نمی دهد (مانند حروف الفبای قالب(template literals) رشته با ${...}
). آنها کاملا ایستا هستند.
اسلش ها زمانی استفاده می شوند که عبارت باقاعده را در زمان نوشتن کد بدانیم – و این رایج ترین حالت است. در حالی که new RegExp
بیشتر زمانی استفاده می شود که ما “در حین انجام کار” نیاز به ایجاد یک regexp از یک رشته که به صورت پویا تولید شده داشته باشیم. برای مثال:
let tag = prompt("کدام تگ HTML را می خواهید پیدا کنید؟", "h2");
let regexp = new RegExp(`<${tag}>`); // خواهد بود /<h2>/ جواب داده شود درست مانند "h2" اگر در اعلان بالا
پرچم ها (Flags)
عبارات باقاعده ممکن است دارای پرچم هایی باشند که بر نحوه جستجو تأثیر بگذارد.
در جاوااسکریپت، تنها 6 مورد از آنها وجود دارد:
i
- با این پرچم، جستجو به حروف کوچک و بزرگ حساس نیست: تفاوتی بین
A
وa
نمی گذارد (به مثال زیر مراجعه کنید). g
- با این پرچم، جستجو برای همه موارد منطبق، بدون آن – فقط اولین موردی که هم خوانی دارد، برگردانده می شود.
m
- حالت چند خطی (در فصل حالت چند خطی anchors ^ $، flag "m" پوشش داده شده است).
s
- حالت
dotall
را فعال می کند، که به یک نقطه.:pattern
اجازه می دهد تا با کاراکتر خط جدیدn\
مطابقت داشته باشد (در فصل کلاس های کاراکتر (Character classes) پوشش داده شده است). u
- پشتیبانی کامل از یونیکد را فعال می کند. پرچم پردازش صحیح surrogate pair را امکان پذیر می کند. اطلاعات بیشتر در مورد آن در فصل یونیکد: پرچم "u" و کلاس {...}p\.
y
- حالت
Sticky
: جستجو در موقعیت دقیق متن (در فصل Sticky flag "y", searching at position پوشش داده شده است)
از اینجا به بعد رنگ بندی درون متن آموزش به این صورت است:
- regexp –
red
(عبارت باقاعده خط قرمز دارد) - string (where we search) –
blue
(چیزی که جستجو می کنیم خط آبی دارد) - result –
green
(نتیجه خط سبز دارد)
جستجو: str.match
همانطور که قبلا ذکر شد، عبارات باقاعده با متدهای رشته ای ادغام می شوند.
متد str.match(regexp)
همه تطابق های regexp
را در رشته str
پیدا می کند.
و دارای 3 حالت کار است:
-
اگر عبارت باقاعده دارای پرچم
g
باشد، آرایهای از همه موارد مطابق با آن را بر می گرداند:let str = "We will, we will rock you"; alert( str.match(/we/gi) ); // We,we (آرایه ای از 2 رشته که مطابقت دارند)
لطفاً توجه کنید که
We
وwe
نتیجه یکسانی می دهند، زیرا پرچمi
باعث می شود که عبارت باقاعده به حروف بزرگ و کوچک حساس نباشد. -
اگر چنین پرچمی وجود نداشته باشد، فقط اولین تطابق را در یک آرایه، با تطابق کامل در ایندکس
0
و برخی جزئیات اضافی در ویژگی ها بر می گرداند:let str = "We will, we will rock you"; let result = str.match(/we/i); // بدون پرچم g alert( result[0] ); // We (اولین تطابق) alert( result.length ); // 1 // Details: alert( result.index ); // 0 (موقعیت تطابق) alert( result.input ); // We will, we will rock you (رشته منبع)
اگر بخشی از عبارت باقاعده در داخل پرانتز قرار بگیرد، ممکن است آرایه، ایندکس های دیگری در کنار ایندکس
0
نیز داشته باشد. ما آن را در فصل Capturing groups پوشش خواهیم داد. -
و در نهایت، اگر هیچ تطابقی وجود نداشته باشد،
null
بر می گرداند. (فرقی نمی کند که پرچمg
وجود داشته باشد یا خیر).این یک فرق ریز و بسیار مهم است. اگر هیچ تطابقی وجود نداشته باشد، یک آرایه خالی دریافت نمی کنیم، بلکه
null
دریافت می کنیم. فراموش کردن آن ممکن است منجر به خطاهایی شود، به عنوان مثال:let matches = "JavaScript".match(/HTML/); // = null if (!matches.length) { // Error: Cannot read property 'length' of null alert("خطا در خط بالایی"); }
اگر می خواهیم نتیجه همواره به صورت یک آرایه باشد، می توانیم آن را به این صورت بنویسیم:
let matches = "JavaScript".match(/HTML/) || []; if (!matches.length) { alert("No matches"); // الان درست کار میکند }
جایگزین کردن: str.replace
روش str.replace(regexp، replacement)
تطابق هایی را که با استفاده از regexp
در رشته str
یافت می شود را با replacement
جایگزین می کند (اگر پرچم g
وجود داشته باشد همه منطبق هستند، در غیر این صورت، فقط اولین مورد تطابق دارد).
برای مثال:
// no flag g
alert( "We will, we will".replace(/we/i, "I") ); // I will, we will
// with flag g
alert( "We will, we will".replace(/we/ig, "I") ); // I will, I will
آرگومان دوم رشته replacement(جایگزین)
است. می توانیم از ترکیب کاراکترهای ویژه در آن برای درج قطعاتی از تطابق استفاده کنیم:
نماد | عمل در رشته جایگزین |
---|---|
$& |
کل تطابق را درج می کند |
$` |
قسمتی از رشته را قبل از تطابق وارد می کند |
$' |
قسمتی از رشته را بعد از تطابق وارد می کند |
$n |
اگرn یک عدد 1-2 رقمی باشد، محتویات پرانتزهای n را درج می کند، اطلاعات بیشتر در مورد آن در فصل Capturing groups |
$<name> |
محتویات پرانتز را با name داده شده درج می کند، اطلاعات بیشتر در مورد آن در فصل Capturing groups |
$$ |
کاراکتر “$” را درج می کند |
مثالی برای $&
:
alert( "I love HTML".replace(/HTML/, "$& and JavaScript") ); // I love HTML and JavaScript
تست کردن: regexp.test
متد regexp.test(str)
حداقل یک تطابق را جستجو می کند، در صورت یافتن true
، در غیر این صورت false
بر می گرداند.
let str = "I love JavaScript";
let regexp = /LOVE/i;
alert( regexp.test(str) ); // true
بعدا در این فصل، عبارات باقاعده بیشتری را یاد می گیریم. مثال های بیشتری را مرور می کنیم و همچنین با روش های دیگری آشنا می شویم.
اطلاعات کامل در مورد متد ها در مقاله Methods of RegExp and String آورده شده است.
خلاصه
- یک عبارت باقاعده از یک الگو و پرچم های اختیاری تشکیل شده است:
g
،i
،m
،u
،s
،y
. - بدون پرچم و نمادهای خاص (که بعداً مطالعه خواهیم کرد)، جستجو توسط regexp مانند جستجوی زیر رشته(substring) است.
- متد
str.match(regexp)
به دنبال تطابق است: اگر پرچمg
وجود داشته باشد، همه آنها را بر می گرداند، در غیر این صورت، فقط اولین مورد را بر می گرداند. - متد
str.replace(regexp، replacement)
تطابق های یافت شده با استفاده ازregexp
را باreplacement
جایگزین می کند: اگر پرچمg
وجود داشته باشد به همه آنها این فرایند را اعمال می کند، در غیر این صورت فقط به اولین مورد اعمال می کند. - متد
regexp.test(str)
اگر حداقل یک مورد مطابقت داشته باشد،true
بر می گرداند، در غیر این صورت،false
بر می گرداند.
نظرات
<code>
استفاده کنید، برای چندین خط – کد را درون تگ<pre>
قرار دهید، برای بیش از ده خط کد – از یک جعبهٔ شنی استفاده کنید. (plnkr، jsbin، codepen…)