شمارشگرها (Quantifiers)
عبارات منظم توسعهیافته، چندین راه را برای اختصاص تعداد دفعات تطبیق یک عنصر (با استفاده از شمارشگرهای مختلف) دارند؛ که به بیان آنها خواهیم پرداخت.
شمارشگر علامت سوال (?) – تطبیق یک عنصر، هیچ یا یک مرتبه
شمارشگر علامت سوال (?) در اصل بدین معنا است که عنصر قبلی را اختیاری کن. فرض کنید میخواهیم اعتبار یک شماره تلفن را بررسی کنیم و در نظر گرفتهایم که یک شماره تلفن معتبر بایستی با یکی از این دو فرم مطابقت داشته باشد:
(nnn) nnn-nnnn
و یا
nnn nnn-nnnn
آن را اینگونه بیان خواهیم کرد:
^\(?[0-9] [0-9] [0-9]\)? [0-9] [0-9] [0-9]- [0-9] [0-9] [0-9] [0-9]$
نکتهای که در این عبارت مورد اهمیت است، این است که کاراکتری که قبل از علامت سوال آمده یعنی () اختیاری است و با این کار میتوانیم هر دو حالت بالا را بررسی کنیم و هر دو تطبیق داده میشوند.
باز هم توجه داشته باشید که از آنجایی که پرانتزها در حالت عادی متاکاراکتر هستند (در ERE) آنها را با یک بکاسلش همراه میکنیم تا بهعنوان کاراکترهای لیترال رفتار کنند.
مثال:
[me@linuxbox ~]$ echo "(555) 123-4567" | grep -E '^\(?[0-9][0-9][0-9]\)? [0-9] [0-9][0-9]$' (555) 123-4567 [me@linuxbox ~]$ echo "555 123-4567" | grep -E '^\(?[0-9][0-9][0-9]\)? [0-9] [0-9][0-9]-[0-9][0-9][0-9][0-9]$' 555 123-4567 [me@linuxbox ~]$ echo "AAA 123-4567" | grep -E '^\(?[0-9][0-9][0-9]\)? [0-9] [0-9][0-9]-[0-9][0-9][0-9][0-9]$' [me@linuxbox ~]$
در مورد اول، کاراکتر echo شده، دارای پرانتز و در مورد دوم، کارامتر echo شده، بدون پرانتز است و در هر دو صورت بهدلیل استفاده از شمارشگر (?) تطبیق صورت میپذیرد. در مورد سوم، به دلیل echo کردن AAA هیچ تطبیقی صورت نمیپذیرد.
شمارشگر ستاره (*) – تطبیق یک عنصر، هیچ یا چند مرتبه
همانند متاکاراکتر علامت سوال (?)، متاکاراکتر ستاره (*) نیز بهمنظور دلالت بر یک آیتم اختیاری بهکار میرود. هر چند بر خلاف قبلی، این بار یک آیتم میتواند تعداد زیادی از دفعات اتفاق بیفتند (نه فقط یک بار).
فرض کنید میخواهیم بفهمیم که آیا یک رشته یک جمله است یا خیر. یک جمله در زبان انگلیسی با حرف بزرگ آغاز شده، سپس شامل تعدادی حروف بزرگ و کوچک و فضاهای خالی است و در آخر با یک نقطه به پایان میرسد. برای تطبیق دادن چنین عبارتی میتوانیم از عبارتی بهصورت زیر استفاده کنیم:
[[:upper:]][[:upper:][:lower:] ]*\.
این عبارت از سه بخش تشکیل شده است: یک براکت که حاوی کلاس کاراکتری [:upper:]، یک براکت حاوی هر دو کلاس کاراکتری [:upper:] و [:lower:] و یک فاصله و یک نقطه که بههمراه بکاسلش نادیده گرفته شده است. این در حالی است که عنصر دومی با متاکاراکتر * همراه شده، در نتیجه پس از حروف بزرگ ابتدایی در جمله، هر تعداد از حروف یزرگ و کوچک و فاصله که قرار بگیرد، باز هم تطبیق صورت میپذیرد.
مثال زیر گویای این مطلب است:
[me@linuxbox ~]$ echo "This works." | grep -E '[[:upper:]][[:upper:][:lower:] ]*\.' This works. [me@linuxbox ~]$ echo "This Works." | grep -E '[[:upper:]][[:upper:][:lower:] ]*\.' This Works. [me@linuxbox ~]$ echo "this does not" | grep -E '[[:upper:]][[:upper:][:lower: ] ]*\.' [me@linuxbox ~]$
شمارشگر علامت جمع (+) – تطبیق یک عنصر، یک یا چند مرتبه
متاکاراکتر (+)، درست مانند (*) عمل میکند، با این تفاوت که حداقل به یک نمونه از عنصر قبلی نیاز دارد تا مطابقت صورت پذیرد. در زیر عبارت منظمی که فقط خصوط حاوی گروهی از یک یا چند کاراکتر الفبایی که با فاصله از هم جدا شدهاند را تطبیق میدهد:
^([[:alpha:]]+ ?)+$
در ادامه، آن را امتحان میکنیم:
[me@linuxbox ~]$ echo "This that" | grep -E '^([[:alpha:]]+ ?)+$' This that [me@linuxbox ~]$ echo "a b c" | grep -E '^([[:alpha:]]+ ?)+$' a b c [me@linuxbox ~]$ echo "a b 9" | grep -E '^([[:alpha:]]+ ?)+$' [me@linuxbox ~]$ echo "abc d" | grep -E '^([[:alpha:]]+ ?)+$' [me@linuxbox ~]$
میبینیم که عبارت “a b 9” مطابقت داده نمیشود
؛ چرا که کاراکتر 9 عددی بوده و الفبایی نیست. همچنین عبارت “abc d” نیز مطابقت داده نمیشود، زیرا بیش از یم فاصله بین دو کاراکتر وجود دارد.
شمارشگر آکولاد {} – تطبیق یک عنصر، به تعداد دفعات تعیین شده
متاکاراکترهای } و { بهمنظور بیان ماکزیمم و مینیمم تعداد دفعات مورد نیاز تطبیق، استفاده میشوند. آنها را میتوان به چهار شیوه مختلف بهکار گرفت که در جدول زیر مشاهده میکنید:
| تعیینکننده | عملکرد |
|---|---|
| {n} | تطبیق عنصر قبلی اگر دقیقا n بار اتفاق بیفتد. |
| {n,m} | تطبیق عنصر قبلی اگر حداقل n بار اتفاق بیفتد ولی از m بار بیشتر رخ ندهد. |
| {n,} | تطبیق عنصر قبلی اگر n بار یا بیشتر اتفاق بیفتد. |
| {,m} | تطبیق عنصر قبلی اگر بیش از m بار اتفاق بیفتد. |
اگر به مثال اخیر (شماره تلفن) بازگردیم، میتوانیم مثال جدید خود را ایجاد کنیم.
مثال قبلی (شماره تلفن):
^\(?[0-9] [0-9] [0-9]\)? [0-9] [0-9] [0-9]- [0-9] [0-9] [0-9] [0-9]$
مثال جدید:
^\(?[0-9]{3}\)? [0-9]{3}-[0-9]{4}$
اکنون آن را امتحان میکنیم:
[me@linuxbox ~]$ echo "(555) 123-4567" | grep -E '^\(?[0-9]{3}\)? [0-9]{3}-[0-
9]{4}$'
(555) 123-4567
[me@linuxbox ~]$ echo "555 123-4567" | grep -E '^\(?[0-9]{3}\)? [0-9]{3}-[0-9]
{4}$'
555 123-4567
[me@linuxbox ~]$ echo "5555 123-4567" | grep -E '^\(?[0-9]{3}\)? [0-9]{3}-[0-9
]{4}$'
[me@linuxbox ~]$
همانطور که مشاهده میشود، بهجای تایپ چند حرف، این بار فقط تعداد دفعات تکرار کاراکتر را در داخل {} قرار میدهیم.
منبع: لینوکسسیزن نوشته فرشید نوتاش حقیقتدرباره فرشید نوتاش حقیقت
همیشه نیازمند یک منبع آموزشی فارسی در حوزه نرمافزارهای آزاد/ متنباز و سیستمعامل گنو/لینوکس بودم. از این رو این رسالت رو برای خودم تعریف کردم تا رسانه «محتوای باز» رو بوجود بیارم.
نوشتههای بیشتر از فرشید نوتاش حقیقتاین سایت از اکیسمت برای کاهش جفنگ استفاده میکند. درباره چگونگی پردازش دادههای دیدگاه خود بیشتر بدانید.
دیدگاهتان را بنویسید