فراری دادن کاراکترها (Escaped characters)
اگر شما بخواهید عملاً یکی از کاراکترهای خاص مانند "^" یا "$" را در معنای واقعی خود تطبیق دهدید، با مشکل مواجه خواهید شد. برای تطبیق این نوع متاکاراکترها در یک متن بک اسلش (\) استفاده کنید. بنابراین "^\"، "\."، و "\\" به ترتیب کاراکترهای معمولی "^" ، "." و "\" را تطبیق می دهد.
تکرارها (Repetitions)
شما دیدید که "{3}" و "*" می توانند برای نشان دادن تکرار یک تک کاراکتر استفاده شوند. بعدها شما خواهید دید که چگونه سینتکس مشابه ای را می توانید برای تکرار زیرعبارتها (subexperssions) استفاده کنید. در جدول زیر شما با چندین روش دیگر جهت تعیین تکرار تطبیق آشنا می شوید:
* به هر تعداد تکرار
+ تعداد یک یا بیشتر تکرار
? تعداد صفر یا یک بار تکرار
{n} به تعداد دقیقا n بار تکرار
{n,m} تعداد حداقل n بار و حداکثر m تکرار
{n,} تعداد حداقل n تکرار و حداکثر تا بی نهایت
بیایید مثالهای بیشتری را بررسی کنیم:
10- \b\w{5,6}\b تمامی کلماتی پنج و شش حرفی را می یابد.
11- \b\d{3}\s\d{3}-\d{4} شماره تلفنهای 10 رقمی را پیدا می کند.
12- \d{3}-\d{2}-\d{4} شماره تامین اجتماعی را تطبیق می دهد.
13- ^\w* اولین کلمه را در خط یا در کل متن تطبیق می دهد.
آخرین مورد را با و بدون تنظیم خاصیت "Multiline" بررسی کنید تا با تغییرات عملکرد کاراکتر ویژه "^" بیشتر آشنا شوید.
کلاسهای کاراکتر
همانگونه که متوجه شدید یافتن alphanumerics، ارقام و فضاهای خالی بسیار ساده به نظر می رسد اما چنانچه بخواهیم. هر چیزی را از یک مجموعه کاراکتر پیدا کنیم چه باید کرد؟ بسیار آسان است. شما فقط می بایست لیستی از کاراکترهای مورد نظر خودتان را درون یک جفت براکت (کروشه) باز و بسته قرار دهید. بنابراین "[aeiou]" حروف صدادار و "[.?!]" علائم نقطه گذاری (punctuation) در انتهای جمله را تشخیص می دهد. توجه داشته باشید که در این مثال کاراکترهای "." و "?" معنای ویژه خود را با قرار گرفتن داخل یک جفت براکت از دست داده و به عنوان یک کاراکتر معمولی تفسیر می شوند. ما همچنین می توانیم محدوده ای از کاراکتر ها مانند [a-z0-9] به معنای "هر حرف الفبایی کوچک یا هر رقمی را تطبیق بده" تعریف کنیم.(مواظب باشید از کلاس کاراکتر های [A-z] یا [z-a] استفاده نکنید. به طور مثال در مورد اول کاراکترهای خاصی بین Z و a وجود دارند که ممکن مد نظر شما نباشد و مورد دوم نیز تطبیقی را برای شما انجام نمی دهد چون توالی کاراکترها را رعایت نکرده اید.)
بیاید یک عبارت پیچیده تری را که شماره تلفنهای را جستجو می کند بررسی کنیم:
14- \(?\d{3}[) ]\s?\d{3}[- ]\d{4}شماره تلفنهای ده رقمی را تطبیق می دهد
توضیح: این عبارت شماره تلفنها معتبر در چندین فرمت مانند"3535-325 (800)" یا "1212 555 650" را پیدا خواهد کرد. "?)\"صفر یا یک پرانتز باز (یا چپ)، "[) ]" پرانتز بسته (یا راست) یا یک space را جستجو می کند. عبارت "?s\" صفر یا یک کاراکتر فضای خالی را جستجو می کند. متاسفانه تمامی موارد شبیه "1212-555 650)" را که پرانتزهای آن موازنه نشده اند را می یابد. در قسمتهای بعدی این مقاله خواهید دید که چگونه از عبارتهای شرطی (یا بهتر بگیم "پیشنهاد متناوب" Alternatives) می توان برای رفع این مشکل بهره جست.
نفی (Negation)
اکثر اوقات نیاز داریم کاراکتر هایی که عضو یک مجموعه از کاراکتر ها که در یک کلاس کاراکتر تعریف شده اند نیستند را بیابیم. جدول زیر نشان خواهد داد که چگونه می توانیم این خاصیت را نیز تعریف کنیم:
W\ هر کاراکتری غیر از alphanumeric را تطبیق می دهد.
S\ هر کاراکتری که فضای خالی نیست را تطبیق می دهد.
D\ هر کاراکتری که عدد نیست را تطبیق می دهد.
B\ موقعیتی که در ابتدا یا انتهای یک کلمه است را تطبیق می دهد.
[x^] هر کاراکتری به جز x را تطبیق می دهد.
[aeiou^] هر کاراکتری به جز حروف صدا دار انگلیسی را تطبیق می دهد.
15- \S+ تمامی رشته هایی را که حاوی کاراکترهای فضای خالی نیستند را تطبیق می دهد
بعداً خواهیم دید که چگونه "نگاه به جلو"(lookahead) و "نگاه به عقب" (lookbehind) برای جستجو بدون استفاده از الگوهای بسیار پیچیده به کار خواهد رفت.
عبارتهای شرطی
16- \b\d{5}-\d{4}\b|\b\d{5}\b پنج و نه رقم کدپستی را می یابد
توضیح: وقتی از عبارتهای شرطی استفاده می کنید، "ترتیب" عبارتهای مورد نظر جهت تطبیق، نظر به اینکه الگوریتم تطبیق سعی در تطبیق دادن از چپ ترین قسمت دارد اهمیت می یابد. اگر ترتیب در این مثال عکس شود، عبارت ابتدا ارقام پنج رقمی کدپستی را پیدا خواهد کرد و یافتن نه رقم اول کدپستی با شکست مواجه خواهد شد.
ما می توانیم از عبارتهای شرطی برای بهبود الگوهای عبارتهای باقاعده جهت یافتن تلفنهای ده رقمی استفاده کنیم. کدهای پستی به وسیله فضاهای خالی یا پرانتزها مرزبندی می شوند.
17- (\(d{3}\)|\d{3}|)\s?\d{3}[- ]\d{4} این عبارت شیوه ای بهتر برای یافتن تلفنهای ده رقمی ارائه می دهد
گروه بندی(Grouping)
پرانتزها ممکن است برای مرز بندی یک زیر عبارت به منظور صدور مجوز تکرار عبارت داخل پرانتزها یا سایر رفتارهای ویژه مورد استفاده قرار گیرند.
18- (\d{1,3}\.){3}\d{1,3} یک شیوه ساده جهت یافتن آدرس IP
توضیح: نخستین قسمت عبارت باقاعده برای یافتن یک یا سه رقم عددی که بعد از آن کاراکتر "\." باشد به کار می رود. عبارت محصور شده(Captured) در داخل پرانتز می بایست سه مرتبه پشت سرهم یافت شوند که خاصیت توسط کمیت سنج "{3}" تعیین شده است، عبارت باقاعده ساده قرار گرفته در انتها نیز حداقل یک و حداکثر سه رقم را بدون اینکه در انتها کاراکتر نقطه را داشته باشد تطبیق می دهد. باز متاسفانه این مثال درست است که آدرسهای IP با یک، دو یا سه رقم اختیاری که با کاراکتر نقطه از هم تفکیک شده اند را به راحتی تطبیق می دهد اما همانگونه که می دانید آدرسهای IP معتبر نمی توانند ارقام بیشتر از 255 داشته باشند. خوب بود اگر می توانستیم الگوریتمی بنویسیم که بتواند ارقام به دام افتاده به الگوی فوق را مانند عدد N همانند عبارت شرطی N<256 مقایسه ای انجام دهد، اما این کار تنها با استفاده از عبارتهای باقاعده غیر ممکن است. مثال بعدی عبارتهای شرطی مختلفی را براساس رقمهای آغازین به منظور تضمین نمودن اینکه اعداد تطبیق یافته به وسیله الگو در محدوده مورد نظر قرار گیرند تحت آزمون قرار می دهد.
19- ((2[0-4]\d|25[0-5]|[01]?\d\d?)\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?) یابنده IP
Analyzer View Expresso
تصویر 2- مثالی از تجزیه کننده Expresso (مربوط به مثال 17)
Expresso دارای ابزاری است که عبارات باقاعده را در یک ساختار درختی به شما نشان داده و توضیحاتی را برای هر قسمت از عبارت باقاعده به شما ارائه می دهد. وقتی یک عبارت باقاعده اشکال زدایی (Debugging) می شود، این ابزار می توان کمک کند در قسمتی از عبارت باقاعده که باعث ایجاد مشکل شده است بیشتر زوم کنید. بهتر است مثال شماره 17 را با استفاده از تجزیه کننده Expresso مورد بررسی بیشتری قرار دهید. پس از اجرای مثال 17 در قسمت Regex Analyzer گره را موجود در درخت را باز کنید. همانند آنچه که در شکل فوق می بینید. ضمن این که بعد از انتخاب یک گره شما می توانید از کلید Partial Match عملکرد تطبیقی قسمتی را که انتخاب کرده اید و با استفاده از کلید Exclude Match عملکرد قسمتهای دیگر عبارت باقاعده را که انتخاب نکرده اید مشاهد کنید.
وقتی زیرعبارت به وسیله پرانتزها گروه بندی می شود، متنی که زیر عبارت تطبیق می دهد جهت اجرای فرآیندهای بیشتر در یک برنامه کامپیوتری یا در خود عبارت باقاعده در دسترس خواهد بود. به طور پیش فرض گروه ها قرار گرفته در داخل پرانتزها به ترتیب از چپ به راست با آغاز از عدد 1 شماره گذاری می شوند. این شماره بندی خودکار را می توانید در Expresso"s skeleton یا در نتیجه به دست آمده بعد از تطبیق موفق مشاهده کنید.
از ارجاع به عقب (backreference) برای جستجوی بازرخداد متن تطبیق یافته قبلی که به وسیله یک گروه محصور شده است، استفاده می شود. برای مثال، "1\" به معنای "متنی را که در گروه اول محصور شده است را تطبیق بده" می باشد. برای مثال عبارت زیر را در نظر بگیرید:
20- \b(\w+)\b\s*\1\b کلمات تکراری را شناسایی می کند
توضیح: این عبارت با محصور کردن یک رشته که دارای حداقل یک کاراکتر "(+w\)" است عمل می کند، ولی فقط اگر آن رشته مستقل بوده و دارای ابتدا و انتها باشد "b(\w+)\b\". سپس هر تعداد فضای خالی را با استفاده از الگوی "*s\" تطبیق داده و به دنبال آن تکرار متن محصور شده اول را "1\" که دارای انتها است تطبیق خواهد داد.
این امکان وجود دارد که به جای شماره بندی اتوماتیک گروه ها از اسم یا شماره های دلخواه خود جهت نامگذاری عبارتهای گروه بندی شده استفاده کنید. در مثال فوق به جای گروه "(+w\)"، می توانیم بنویسیم
"(?<Word>\w+)"
که به معنای این است که اسم گروه محصور شده را با عبارت "Word" تعیین کرده ام. به منظور ارجاع به این گروه (یا همان ارجاع به عقب جهت ایجاد بالانس) می بایست نوشت
"\k<Word>"
. مثال زیر بررسی کنید:
21- \b(?<Word>\w+)\s*\k<Word>\b استفاه از نامگذاری گروه محصور شده جهت تطبیق کلمات تکرار شده
این مثال را در Expresso تست کنید و نتایج تطبیق را جهت مشاهده محتوای گروه های دارای نام بسط دهید.
استفاده از پرانتزها، بسیاری از المانهای سینتکسهای مورد نظر را در اختیار ما قرار می دهد. بعضی از پرکاربردترین آنها به شکل خلاصه در جدول زیر توضیح داده شده اند:
محصور شده ها (Captures)
(exp) exp را تطبیق داده و گروه محصور شده به طور اتوماتیک شماره گذاری می کند
(?<name>exp) exp را تطبیق داده و به گروه محصور شده نام name را تخصیص می دهد
(?:exp) exp را تطبیق می دهد ولی محصور سازی را انجام نمی دهد
نگاه به اطراف (Lookarounds)
(?=exp) به جلو می کند و اگر پسوند exp داشت عبارت قبل از خود را تطبیق می دهد
(?<=exp) به عقب نگاه می کند و اگر پیشوند exp داشت عبارت بعد از خود را تطبیق می دهد
(?!exp) به جلو نگاه می کند اگر پسوند exp نداشت عبارت قبل از خود را تطبیق می دهد
(?<!exp) به عقب نگاه می کند و اگر پیشوند exp نداشت عبارت بعد از خود را تطبیق می دهد
توضیح (Comment)
(?#comment) درج توضیحات در عبارت باقاعده
ما قبلاً درخصوص دو مورد اول جدول فوق صحبت کردیم. سومین مورد "(exp:?)" رفتار تطبیقی را تغییر نمی دهد و تنها تفاوت این مورد با دو مورد قبلی در این است که عبارت داخل پرانتز در یک گروه دارای نام یا شماره گذاری شده محصور نمی شود.
عناوین یادداشتهای وبلاگ
بایگانی
دسته بندی موضوعی