فصل ‎18‎- عبارت‌های منظم

‎18.1‎- مقدمه‌ای کوتاه بر عبارت‌های منظم

یک عبارت، رشته‌ای از کاراکترها است. آن کاراکترهایی که دارای یک ترجمان مافوق و ماورای معنی لفظی‌شان هستند فوق کاراکتر نامیده می‌شوند. برای مثال، یک علامت نقل‌قول، ممکن است مشخص کننده سخن یک شخص، رونوشت، یا یک فوق معنی ‎[1]‎ برای علامت‌های متعاقب آن باشد. عبارت‌های منظم، مجموعه کاراکترها و/یا فوق‌کاراکترهایی هستند که الگوها را منطبق (یا تعریف) می‌کنند.

یک عبارت منظم شامل یک یا چند مورد از موارد زیر است:

  • یک مجموعه کاراکتر. اینها کاراکترهایی هستند که معنی لفظی‌شان را حفظ می‌کنند. ساده‌ترین نوع عبارت منظم تنها متشکل از یک مجموعه کاراکتر، بدون هیچ فوق‌کارکتر است.

  • یک anchor (مهار). این‌ها موقعیتی در یک سطر متن را که برای انطباق RE (عبارت منظم) است، مشخص می‌کنند. برای مثال، ^‏، و $ مهار هستند.

  • Modifiers (اصلاح‌کننده‌ها). اینها محدوده متنی را که برای انطباق عبارت منظم است، محدود یا گسترده ‎(modify)‎ می‌کنند. اصلاح‌کننده‌ها شامل ستاره، براکت‌ها، و backslash هستند.

موارد استفاده‌ اصلی ‏REها (عبارت‌های منظم) جستجوهای متن و دستکاری رشته‌ها است. یک RE، کاراکتر منفرد یا مجموعه‌ای از کاراکترها --یک رشته یا بخشی از یک رشته-- را مطابقت می‌دهد.

  • ستاره -- * -- با هر تعداد تکرار رشته کاراکتر یا RE مقدم بر آن، از جمله صفر مورد مطابقت می‌کند.

    «‎1133*‎» با ‎11‎ به اضافه یک یا چند ‎3‎ مطابقت می‌کند: 113‏، 1133‏، 1133333‏، و به همین ترتیب.

  • نقطه -- . -- با هر کاراکتر واحد، به غیر از سطر جدید مطابقت می‌کند. ‎[2]‎

    «‎13.‎» با ‎13‎ بعلاوه حداقل یک کاراکتر دیگر (هر کاراکتری از جمله کاراکتر فاصله) مطابقت می‌کند: 133‏، 1333‏، اما با ‎13‎ خیر (چون کاراکتر اضافی غایب است).

    برای نمایش تجربی انطباق کاراکتر منفرد نقطه مثال ‎16-18‎ را ببینید.

  • مترجم: شاید توجه به این مثال به درک بهتر عبارت منظم و نقش ستاره و نقطه کمک نماید
    bash$ cat file1            file1 نمایش محتوای
    
    #1	1111111
    #2	1113113333333333
    #3	11132113321211233
    #4	11311
    #5	13
    #6	137
    #7	1133.
    #8	113312.
    #9	1112.
    
    
    bash$ grep 133 file1                      بدون عبارت منظم grep کاربرد                                    
    
    #2	1113113333333333                      مطابقت می‌کند ‎133‎ فقط با
    #3	11132113321211233
    #7	1133.
    #8	113312.
    
    
    bash$ grep 113* file1                است ‎3‎ ستاره به معنای هیچ یا چند
    
    #1	1111111                           ‎3‎ سه مورد تطابق پیاپی بدون
    #2	1113113333333333        ‎3‎ ویک تطابق با چندین ‎3‎ یک تطابق بدون
    #3	11132113321211233
    #4	11311
    #7	1133.
    #8	113312.
    #9	1112.
    
    
    bash$ grep 13. file1                      نقطه یعنی یک کاراکتر منفرد
    
    #2	1113113333333333          ‎133‎  و یکی  ‎131‎ دو مورد انطباق یکی
    #3	11132113321211233         ‎132‎  و یکی  ‎133‎ دو مورد انطباق یکی
    #4	11311   ‎                     1‎ و یک کاراکتر منفرد ‎13‎
    #6	137                          ‎7‎ و یک کاراکتر منفرد ‎13‎
    #7	1133.
    #8	113312.
    
  • کاراکتر هشتک -- ^ -- بر ابتدای سطر منطبق می‌شود، اما گاهی اوقات، بر حسب مضمون، معنی یک مجموعه کاراکتر در یک ‎RE‎ را منفی می‌کند.

  • علامت دلار -- $ -- در انتهای یک RE با انتهای یک سطر مطابقت می‌کند.

    «‎XXX$‎» با XXX در انتهای یک سطر مطابقت می‌کند.

    ‎^$‎ با سطر خالی مطابقت می‌کند.

  • براکت‌ها -- ‎[...]‎ -- مجموعه‌ای از کاراکترها را برای انطباق در یک RE واحد محصور می‌کنند.

    «‎[xyz]‎» با هر کارکتری از کاراکترهای x‏، y‏، یا z مطابقت می‌کند.

    «‎[c-n]‎» با هر کاراکتری در محدوده c تا n مطابقت می‌کند.

    «‎[B-Pk-y]‎» با هر یک از کاراکترها در محدوده B تا P و k تا y مطابقت می‌کند.

    «‎[a-z0-9]‎» با هر حرف کوچک منفرد یا هر رقمی مطابقت می‌نماید.

    «‎[^b-d]‎» با هر کارکتری به غیر از آنها که در محدوده b تا d هستند مطابقت دارد. این یک نمونه از ^ در منفی کردن یا وارونه کردن معنی RE پس از آن است (عهده‌دار وظیفه‌ای مشابه ! در یک مضمون متفاوت است).

    رشته‌های ترکیب شده از کاراکترهای محصور در براکت‌ها، با الگوهای کلمات رایج مطابقت می‌کنند. «‎[Yy][Ee][Ss]‎» با yes‏، Yes‏، YES‏، yEs، مطابقت می‌کند‏، و به همین ترتیب. «‎[0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9]‎» با هر شماره تامین اجتماعی مطابقت می‌کند.

  • کاراکتر backslash -- \ -- یک کاراکتر خاص را escape (معاف) می‌کند، بدین معنی که آن کاراکتر به طور لفظی تفسیر می‌گردد (و بنابراین دیگر خاص نیست).

    یک «‎\$‎» به جای معنای انتهای سطر در یک RE به معنی لفظی «$» برمی‌گردد. همچنین یک «\\» دارای معنی لفظی «\» است.

  • «براکت‌های زاویه‌ای» escape شده -- ‎\<...\>‎ -- اطراف کلمه را علامت می‌زنند.

    این براکت‌ها باید معاف شده باشند، چون در غیر این صورت آنها فقط دارای مفهوم لفظی کاراکترشان هستند.

    «‎\<the\>‎» با کلمه «the» مطابقت می‌کند، اما با کلمات «them»‏، «there»‏، «other»‎‏، و غیره مطابقت نمی‌کند.

  • bash$ cat textfile
    
     This is line 1, of which there is only one instance.
     This is the only instance of line 2.
     This is line 3, another line.
     This is line 4.
    
    bash$ grep 'the' textfile
    
     This is line 1, of which there is only one instance.
     This is the only instance of line 2.
     This is line 3, another line.
    
    bash$ grep '\<the\>' textfile
    
    This is the only instance of line 2.

  • عبارت‌های منظم توسعه یافته. فوق‌کاراکترهای اضافی افزوده شده به مجموعه اصلی. اینها در egrep‏، awk‏، و Perl استفاده شدند.

  • علامت سوال -- ? -- با صفر یا یک RE قبلی مطابقت می‌کند. در اصل برای انطباق یک کاراکتر واحد استفاده می‌شود.

  • علامت به‌اضافه -- + -- با یک یا چند RE قبلی مطابقت می‌کند. نقشی مشابه * به عهده دارد، اما با صفر مورد وجود کاراکتر مطابقت نمی‌کند.

  • #نگارش‌ گنوی sed و awk می‌تواند از «+»  استفاده نماید، اما باید escape شده باشد
    
    echo a111b | sed -ne '/a1\+b/p'
    echo a111b | grep 'a1\+b'
    echo a111b | gawk '/a1+b/'
    #تمام موارد فوق معادل هم هستند.
    
    #با تشکر از ‎S.C.‎

  • براکت‌های کمانی (ابروها) escape شده -- ‎\{ \}‎ -- بیان کننده تعداد موارد وجود یک RE مقدم بر آنها برای تطابق هستند.

    لازم است این براکت‌ها معاف شده باشند چون در غیر این صورت آنها فقط دارای معنی لفظی‌شان هستند. این کاربرد، بخشی از مجموعه اصلی RE نیست.

    «‎[0-9]\{5\}‎» درست با پنج رقم (کاراکترها در محدوده ‎0‎ تا ‎9‎) مطابقت می‌کند.

    ابروها در نگارش awk «کلاسیک» (غیر موافق با ‎POSIX‎) به عنوان یک RE معتبر نیستند . به هر حال، نگارش awk توسعه یافته گنو، gawk، دارای گزینه ‎--re-interval‎ است که آنها را مجاز می‌سازد (بدون اینکه escape شده باشند).

    bash$ echo 2222 | gawk --re-interval '/2{3}/'
    
    2222

    Perl و بعضی نگارش‌های egrep معاف کردن ابروها را لازم ندارند.

  • پرانتزها -- ( ) -- گروهی از REها را محصور می‌کنند. آنها با عملگر | و در استخراج رشته فرعی با استفاده از expr مفید هستند.

  • عملگر -- | -- «یا» در عبارت منظم با هر یک از مجموعه کاراکترهای پیشنهادی مطابقت می‌دهد.

  • bash$ egrep 're(a|e)d' misc.txt
    People who read seem to be better informed than those who do not.
     The clarinet produces sound by the vibration of its reed.

برخی نگارش‌های sed‏، ed‏، و ex، همانطور که برنامه‌های سودمند گنو عمل می‌کنند، از نسخه‌های escape شده عبارت‌های منظم توسعه‌یافته‌ شرح داده شده فوق، پشتیبانی می‌کنند.

  • کلاس‌های کاراکتر ‏POSIX.‏ ‎[:class:]‎

    این یک روش جایگزین برای تعیین محدوده کاراکترها جهت انطباق است.

  • ‎[:alnum:]‎ بر کاراکترهای الفبایی یا عددی منطبق می‌گردد. این کلاس معادلی برای ‎A-Za-z0-9‎ است.

  • ‎[:alpha:]‎ با کاراکترهای الفبایی مطابقت دارد. این معادلی برای ‎A-Za-z‎ است.

  • ‎[:blank:]‎ با یک فاصله یا یک tab مطابقت می‌کند.

  • ‎[:cntrl:]‎با کاراکترهای کنترلی مطابقت می‌کند.

  • ‎[:digit:]‎با ارقام (دهدهی) مطابقت می‌کند. این معادلی برای ‎0-9‎ است.

  • ‎[:graph:]‎ ‏(کاراکترهای قابل چاپ ترسیمی). با کاراکترهای ASCII در محدوده ‎33‎ تا ‎126‎ منطبق می‌شود. این مانند ‎[:print:]‎ در پایین، اما به استثنای کاراکتر فاصله است.

  • ‎[:lower:]‎با کاراکترهای الفبایی کوچک مطابقت می‌کند. این معادل است با ‎a-z‎.

  • ‎[:print:]‎ ‏(کاراکترهای قابل چاپ). این با کاراکترها در محدوده اسکی ‎32 - 126‎ مطابقت می‌کند. این همانند ‎[:graph:]‎ فوق است، اما به اضافه کاراکتر فاصله.

  • ‎[:space:]‎ بر کاراکترهای فضای سفید (فاصله و tab افقی). منطبق می‌گردد

  • ‎[:upper:]‎ با کاراکترهای الفبایی بزرگ مطابقت می‌کند. این معادل ‎A-Z‎ است.

  • ‎[:xdigit:]‎ با ارقام هگزا دسیمال مطابقت می‌کند. این معادلی برای ‎0-9A-Fa-f‎ است.

  • important

    به طور کلی لازم است کلاس‌های کاراکتر POSIX در نقل‌قول‌ها یا براکت‌های دوتایی ‎([[ ]])‎ قرار بگیرند.

    bash$ grep [[:digit:]] test.file
    
     abc=723

    # ...
    if [[ $arow =~ [[:digit:]] ]]   #                    ورودی عددی است؟
    then                            #                  کلاس کاراکتر POSIX
      if [[ $acol =~ [[:alpha:]] ]] # عدد با یک حرف دنبال شده؟ غیر مجاز!
    # ...
    # از اسکریپت مثال ‎ktour.sh

    این کلاس‌های کاراکتری حتی ممکن است با globbing، برای یک دامنه محدود به کار بروند.

    bash$ ls -l ?[[:digit:]][[:digit:]]?
    
    -rw-rw-r--    1 bozo  bozo         0 Aug 21 14:47 a33b

    کلاس‌های کاراکتر POSIX در مثال ‎16-21‎ و مثال ‎16-22‎ استفاده شده‌اند.

Sed‏، awk‏، و Perl، که در اسکریپت‌ها به عنوان فیلتر به کار رفته‌اند، موقع غربال کردن یا تبدیل کردن فایل‌ها یا جریان‌های ورودی-خروجی، عبارت‌های منظم را به عنوان شناسه دریافت می‌کنند. برای توضیحات این مطلب مثال ‎A-12‎ و مثال ‎A-16‎ را ملاحظه نمایید.

مرجع استاندارد این مبحث پیچیده، «مهارت در عبارت‌های منظم Friedl» است. ‎Sed & Awk‎ توسط ‎Dougherty‎ و ‎Robbins‎ نیز یک بررسی بسیار شفاف از عبارت‌های منظم ارایه می‌دهد. برای اطلاعات بیشتر در مورد این کتابها بخش کتاب‌شناسی را ببینید.

یادداشت‌ها

‎[1]‎

فوق معنی، معنای یک جمله یا یک عبارت در سطحی ماورای ظاهر آن است. برای مثال، معنی لفظی عبارت منظم عبارت متداولی است که از عرف پذیرفته شده پیروی می‌کند. فوق معنی آن، همچنانکه در طول این فصل بحث گردید، به طور جدی متفاوت از آن است.

‎[2]‎

چون sed‏، awk‏، و grep سطرهای منفرد را پردازش می‌کنند، به طور معمول یک سطر جدید برای انطباق وجود نخواهد داشت. در آن حالت‌هایی که یک سطر جدید در یک عبارت چند سطری موجود باشد، نقطه با سطر جدید مطابقت خواهد نمود.

#!/bin/bash
sed -e 'N;s/.*/[&]/' << EOF   # Here Document
line1
line2
EOF
# خروجی:
# [line1
# line2]
echo

awk '{ $0=$1 "\n" $2; if (/line.1/) {print}}' << EOF
line 1
line 2
EOF
# خروجی:
# line
# 1

#با تشکر از ‎S.C.‎
exit 0