سه شنبه ۲۷ شهريور ۱۴۰۳
Tut24 آموزش برنامه نویسی و مجله تخصصی فناوری ورود/عضویت

آموزش سی شارپ - عبارات منظم

یک عبارت منظم (regular expression) الگویی است که می‌تواند با یک متن ورودی مطابقت داشته باشد. فریمورک .Net یک موتور عبارات منظم را فراهم می‌کند که امکان انطباق با این الگوها را فراهم می‌سازد. یک الگو شامل یک یا چند کاراکتر ثابت، عملگر یا ساختار است.

ساختارها برای تعریف عبارات منظم

دسته‌های مختلفی از کاراکترها، عملگرها و ساختارها وجود دارد که به شما امکان تعریف عبارات منظم را می‌دهد. در ادامه هر کدام از این ساختارها را بررسی می کنیم

کلاس Regex

کلاس Regex برای نمایش یک عبارت منظم استفاده می‌شود. این کلاس دارای متدهای متداول زیر است:

ردیف متدها و توضیحات
1

public bool IsMatch(string input)

نشان می‌دهد که عبارت منظم مشخص شده در سازنده Regex، با یک رشته ورودی مشابهت دارد یا خیر.

2

public bool IsMatch(string input, int startat)

نشان می‌دهد که عبارت منظم مشخص شده در سازنده Regex، با یک رشته ورودی مشابهت دارد یا خیر، با شروع از موقعیت مشخص شده در رشته.

3

public static bool IsMatch(string input, string pattern)

نشان می‌دهد که عبارت منظم مشخص شده، با یک رشته ورودی مشابهت دارد یا خیر.

4

public MatchCollection Matches(string input)

برای جستجو در رشته ورودی به دنبال همه مواردی که با یک عبارت منظم مطابقت دارند استفاده می‌شود.

5

public string Replace(string input, string replacement)

در یک رشته ورودی مشخص، همه رشته‌هایی که با یک الگوی عبارت منظم مطابقت دارند را با یک رشته جایگزین مشخص جایگزین می‌کند.

6

public string[] Split(string input)

یک رشته ورودی را به آرایه‌ای از زیررشته‌ها در موقعیت‌هایی که با الگوی عبارت منظم مشخص شده در سازنده Regex مطابقت دارند تقسیم می‌کند.

برای لیست کاملی از متدها و خصوصیات، لطفاً مستندات Microsoft درباره رجکس در سی شارپ را مطالعه کنید.

مثال ۱

مثال زیر کلماتی را پیدا می‌کند که با حرف 'S' شروع می‌شوند:

using System;
using System.Text.RegularExpressions;

namespace RegExApplication {
   class Program {
      private static void showMatch(string text, string expr) {
         Console.WriteLine("The Expression: " + expr);
         MatchCollection mc = Regex.Matches(text, expr);
         
         foreach (Match m in mc) {
            Console.WriteLine(m);
         }
      }
      static void Main(string[] args) {
         string str = "A Thousand Splendid Suns";
         
         Console.WriteLine("Matching words that start with 'S': ");
         showMatch(str, @"\bS\S*");
         Console.ReadKey();
      }
   }
}

هنگامی که کد بالا کامپایل و اجرا می شود، نتیجه زیر را ایجاد می کند -

Matching words that start with 'S':
The Expression: \bS\S*
Splendid
Suns

مثال ۲

مثال زیر کلماتی را پیدا می‌کند که با حرف 'm' شروع می‌شوند و با حرف 'e' ختم می‌شوند:

using System;
using System.Text.RegularExpressions;

namespace RegExApplication {
   class Program {
      private static void showMatch(string text, string expr) {
         Console.WriteLine("The Expression: " + expr);
         MatchCollection mc = Regex.Matches(text, expr);
         
         foreach (Match m in mc) {
            Console.WriteLine(m);
         }
      }
      static void Main(string[] args) {
         string str = "make maze and manage to measure it";

         Console.WriteLine("Matching words start with 'm' and ends with 'e':");
         showMatch(str, @"\bm\S*e\b");
         Console.ReadKey();
      }
   }
}

هنگامی که کد بالا کامپایل و اجرا می شود، نتیجه زیر را ایجاد می کند -

Matching words start with 'm' and ends with 'e':
The Expression: \bm\S*e\b
make
maze
manage
measure

مثال 3

این مثال جایگزین فضای سفید اضافی - می شود

using System;
using System.Text.RegularExpressions;

namespace RegExApplication {
   class Program {
      static void Main(string[] args) {
         string input = "Hello   World   ";
         string pattern = "\\s+";
         string replacement = " ";
         
         Regex rgx = new Regex(pattern);
         string result = rgx.Replace(input, replacement);

         Console.WriteLine("Original String: {0}", input);
         Console.WriteLine("Replacement String: {0}", result);    
         Console.ReadKey();
      }
   }
}

هنگامی که کد بالا کامپایل و اجرا می شود، نتیجه زیر را ایجاد می کند -

Original String: Hello World   
Replacement String: Hello World   

 

C# - کاراکترهای گریز (Character Escapes)


 

این‌ها در واقع کاراکترهای ویژه یا کاراکترهای گریز هستند. کاراکتر بک‌اسلش (\) در یک عبارت با قاعده نشان می‌دهد که کاراکتری که پس از آن قرار می‌گیرد، یا یک کاراکتر ویژه است یا باید به صورت حرف باشد.

جدول زیر کاراکترهای گریز را نشان می‌دهد:

کاراکتر گریز توضیحات الگو مطابقت‌ها
\a با مطابقت با یک کاراکتر زنگ، \u0007. \a "\u0007" در "اخطار!" + '\u0007'
\b در یک کلاس کاراکتر، با مطابقت با یک کاراکتر بک‌اسپیس، \u0008. [\b]{3,} "\b\b\b\b" در "\b\b\b\b"
\t با مطابقت با یک تب، \u0009. (\w+)\t "نام\t"، "آدرس\t" در "نام\tآدرس\t"
\r با مطابقت با یک کاراکتر برگشت‌خط، \u000D. (\r با کاراکتر تازه خط، \n، معادل نیست.) \r\n(\w+) "\r\nسلام" در "\r\nسلام\nجهان."
\v با مطابقت با یک تب عمودی، \u000B. [\v]{2,} "\v\v\v" در "\v\v\v"
\f با مطابقت با یک فرم فید، \u000C. [\f]{2,} "\f\f\f" در "\f\f\f"
\n با مطابقت با یک خط جدید، \u000A. \r\n(\w+) "\r\nسلام" در "\r\سلام\nجهان."
\e با مطابقت با یک کاراکتر گریز، \u001B. \e "\x001B" در "\x001B"
\nnn استفاده از نمایش هشت‌گانه برای مشخص کردن یک کاراکتر (nnn شامل حداکثر سه رقم است). \w\040\w "a b"، "c d" در "a bc d"
\x nn استفاده از نمایش شانزده‌گانه برای مشخص کردن یک کاراکتر (nn شامل دقیقاً دو رقم است). \w\x20\w "a b"، "c d" در "a bc d"
\c X\c x با مطابقت با کاراکتر کنترل ASCII که توسط X یا x مشخص می‌شود، که X یا x حرف کاراکتر کنترل است. \cC "\x0003" در "\x0003" (Ctrl-C)
\u nnnn با مطابقت با یک کاراکتر یونیکد با استفاده از نمایش شانزده‌گانه (دقیقاً چهار رقم، به صورت nnnn نمایش داده می‌شود). \w\u0020\w "a b"، "c d" در "a bc d"
\ وقتی پس از آن یک کاراکتر که به عنوان یک کاراکتر گریز شناخته نمی‌شود قرار می‌گیرد، با مطابقت با آن کاراکتر. \d+[\+-x\*]\d+\d+[\+-x\*\d+ "2+2" و "3*9" در "(2+2) * 3*9"

C# - کلاس‌های کاراکتری


 

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

کلاس کاراکتری توضیح الگو مطابقت‌ها
[character_group] مطابقت با هر کاراکتر تک در character_group. به طور پیش‌فرض، مطابقت بین حروف بزرگ و کوچک حساس است. [mn] "m" در "mat"، "m" و "n" در "moon"
[^character_group] منفی: مطابقت با هر کاراکتر تک که در character_group نباشد. به طور پیش‌فرض، مطابقت بین حروف بزرگ و کوچک در character_group حساس است. [^aei] "v" و "l" در "avail"
[ first - last ] محدوده‌ی کاراکتر: مطابقت با هر کاراکتر تک در محدوده‌ی از first تا last. [b-d] [b-d]irds Birds Cirds Dirds
. علامت جایگزین: مطابقت با هر کاراکتر تک به جز \n. a.e "ave" در "have"، "ate" در "mate"
\p{ name } مطابقت با هر کاراکتر تک در دسته‌بندی عمومی یونیکد یا بلوک نام‌گذاری‌شده‌ی مشخص شده توسط name. \p{Lu} "C" و "L" در "City Lights"
\P{ name } مطابقت با هر کاراکتر تک که در دسته‌بندی عمومی یونیکد یا بلوک نام‌گذاری‌شده‌ی مشخص شده توسط name نباشد. \P{Lu} "i" و "t" و "y" در "City"
\w مطابقت با هر کاراکتر کلمه‌ای. \w "R" و "o" و "m" و "1" در "Room#1"
\W مطابقت با هر کاراکتر غیر از کاراکتر کلمه‌ای. \W "#" در "Room#1"
\s مطابقت با هر کاراکتر فضای سفید. \w\s "D " در "ID A1.3"
\S مطابقت با هر کاراکتر غیر از فضای سفید. \s\S " _" در "int __ctr"
\d مطابقت با هر رقم دسیمال. \d "4" در "4 = IV"
\D مطابقت با هر کاراکتر غیر از رقم دسیمال. \D " " و "=" و " " و "I" و "V" در "4 = IV"

عناصر محدودکننده عبارات با قاعده (Anchors Regular Expressions)


 

عناصر محدودکننده به یک الگو امکان موفقیت یا عدم موفقیت نسبت به موقعیت فعلی در رشته را می‌دهد. جدول زیر عناصر محدودکننده را لیست می‌کند −

تاییدیه توضیحات الگو مطابقت
^ مطابقت باید از ابتدای رشته یا خط شروع شود. ^\d{3} "567" در "567-777-"
$ مطابقت باید در انتهای رشته یا قبل از \n در انتهای خط یا رشته رخ دهد. -\d{4}$ "-2012" در "8-12-2012"
\A مطابقت باید در ابتدای رشته رخ دهد. \A\w{3} "Code" در "Code-007-"
\Z مطابقت باید در انتهای رشته یا قبل از \n در انتهای رشته رخ دهد. -\d{3}\Z "-007" در "Bond-901-007"
\z مطابقت باید در انتهای رشته رخ دهد. -\d{3}\z "-333" در "-901-333"
\G مطابقت باید در نقطه‌ای رخ دهد که مطابقت قبلی پایان یافته است. \\G\(\d\) "(1)", "(3)", "(5)" در "(1)(3)(5)[7](9)"
\b مطابقت باید در مرز بین کاراکتری عبارت مجاز (\w) و یک کاراکتر غیر مجاز (\W) رخ دهد. \w "R", "o", "m" و "1" در "Room#1"
\B مطابقت نباید در مرزی \b رخ دهد. \Bend\w*\b "ends", "ender" در "end sends endure lender"

ساختارهای گروه‌بندی


 

ساختارهای گروه‌بندی زیرعبارت‌های عبارت منظم را مشخص می‌کنند و زیررشته‌هایی از رشته ورودی را ذخیره می‌کنند. جدول زیر مشخصهای ساختارهای گروه‌بندی را نمایش می‌دهد −

ساختار گروه‌بندی توضیحات الگو تطبیق‌ها
( زیرعبارت ) زیرعبارت تطبیق‌یافته را ذخیره می‌کند و یک شماره ترتیبی صفر مبتنی روی آن اختصاص می‌دهد. (\w)\1 "ee" در "deep"
(?< نام >زیرعبارت) زیرعبارت تطبیق‌یافته را در گروهی با نام ذخیره می‌کند. (?< double>\w)\k< double> "ee" در "deep"
(?< نام۱ -نام۲ >زیرعبارت) یک تعریف گروه تعادلی مشخص می‌کند. (((?'Open'\()[^\(\)]*)+((?'Close-Open'\))[^\(\)]*)+)*(?(Open)(?!))$ "((1-3)*(3-1))" در "3+2^((1-3)*(3-1))"
(?: زیرعبارت) یک گروه غیرذخیره‌کننده را تعریف می‌کند. Write(?:Line)? "WriteLine" در "Console.WriteLine()"
(?imnsx-imnsx:زیرعبارت) گزینه‌های مشخص شده را در محدوده زیرعبارت فعال یا غیرفعال می‌کند. A\d{2}(?i:\w+)\b "A12xl"، "A12XL" در "A12xl A12XL a12xl"
(?= زیرعبارت) ادعای مشاهده بازو به جلو بدون طول صفر. \w+(?=\.) "is"، "ran"، و "out" در "He is. The dog ran. The sun is out."
(?! زیرعبارت) ادعای مشاهده بازو به جلو با طول صفر منفی. \b(?!un)\w+\b "sure"، "used" در "unsure sure unity used"
(?< =زیرعبارت) ادعای مشاهده بازو به عقب بدون طول صفر. (?< =19)\d{2}\b "99"، "50"، "05" در "1851 1999 1950 1905 2003"
(?< ! زیرعبارت) ادعای مشاهده بازو به عقب با طول صفر منفی. (?< !19)\d{2}\b "51"، "03" در "1851 1999 1950 1905 2003"
(?> زیرعبارت) زیرعبارت بدون پشتیبانی از بازگشت (یا "طماعانه"). [13579](?>A+B+) "1ABB"، "3ABB"، و "5AB" در "1ABB 3ABBC 5AB 5AC"

کمیت سنج (Quantifier)


کمیت سنجها مشخص می‌کنند که چند نمونه از عنصر قبلی (که می‌تواند یک کاراکتر، یک گروه یا یک کلاس کاراکتر باشد) باید در رشته ورودی حضور داشته باشد تا یک تطابق رخ دهد.

کمیت سنج توضیحات الگو تطابق‌ها
* بازگویی عنصر قبلی صفر یا بیش از صفر بار. \d*\.\d ".0", "19.9", "219.9"
+ بازگویی عنصر قبلی یک یا بیش از یک بار. "be+" "bee" در "been"، "be" در "bent"
? بازگویی عنصر قبلی صفر یا یک بار. "rai?n" "ran", "rain"
{ n } بازگویی عنصر قبلی به طور دقیق n بار. ",\d{3}" ",043" در "1,043.6"، ",876"، ",543" و ",210" در "9,876,543,210"
{ n ,} بازگویی عنصر قبلی حداقل n بار. "\d{2,}" "166", "29", "1930"
{ n , m } بازگویی عنصر قبلی حداقل n بار و حداکثر m بار. "\d{3,5}" "166", "17668" "19302" در "193024"
*? بازگویی عنصر قبلی صفر یا بیش از صفر بار، اما به حداقل تعداد ممکن. \d*?\.\d ".0", "19.9", "219.9"
+? بازگویی عنصر قبلی یک یا بیش از یک بار، اما به حداقل تعداد ممکن. "be+?" "be" در "been"، "be" در "bent"
?? بازگویی عنصر قبلی صفر یا یک بار، اما به حداقل تعداد ممکن. "rai??n" "ran", "rain"
{ n }? بازگویی عنصر قبلی به طور دقیق n بار. ",\d{3}?" ",043" در "1,043.6"، ",876"، ",543" و ",210" در "9,876,543,210"
{ n ,}? بازگویی عنصر قبلی حداقل n بار، اما به حداقل تعداد ممکن. "\d{2,}?" "166", "29", "1930"
{ n , m }? بازگویی عنصر قبلی بین n و m بار، اما به حداقل تعداد ممکن. "\d{3,5}?" "166", "17668" "193", "024" در "193024"

ساختارهای برگشتی مرجع


ساختارهای برگشتی امکان شناسایی یک زیرعبارت قبلی که در عبارت منظم همان عبارت منظم قبلی تطابق داده شده را فراهم می‌کند.

جدول زیر فهرستی از این ساختارها را نشان می‌دهد:

ساختار برگشتی توضیحات الگو تطابق‌ها
\عدد برگشتی. بازماندی عدد شماره‌دار از زیربیانی. (\w)\1 "ee" در "seek"
\k<نام> برگشتی با نام. بازماندی مقدار یک بیانیه با نام. (?<char>\w)\k<char> "ee" در "seek"

ساختارهای تناوب در عبارت‌های منظم 


ساختارهای جایگزینی (Alternation constructs) عبارت‌های منظم را به گونه‌ای تغییر می‌دهند که امکان تطبیق با یکی از گزینه‌های مختلف را فراهم می‌کنند. جدول زیر ساختارهای جایگزینی را لیست می‌کند:

ساختار جایگزینی شرح الگو مطابقت‌ها
| بازهم تطبیق با هر یک از عناصر مجزا که با نماد خط عمودی (|) جدا شده‌اند. th(e|is|at) "the", "this" در "this is the day."
(?( expression )yes | no ) مطابقت با yes در صورتی که عبارت مطابقت داشته باشد؛ در غیر این صورت، مطابقت با بخش اختیاری no. عبارت به عنوان یک ادعا با طول صفر تفسیر می‌شود. (?(A)A\d{2}\b|\b\d{3}\b) "A10", "910" در "A10 C103 910"
(?( name )yes | no ) مطابقت با yes در صورتی که بازیابی نام دار مطابقت داشته باشد؛ در غیر این صورت، مطابقت با بخش اختیاری no. (?< quoted>")?(?(quoted).+?"|\S+\s) Dogs.jpg, "Yiska playing.jpg" در "Dogs.jpg "Yiska playing.jpg""

جایگزینی (Substitution)


جایگزینی‌ها در الگوهای جایگزینی استفاده می‌شوند. جدول زیر فهرستی از جایگزینی‌ها را نشان می‌دهد:

نویسه توضیح الگو الگوی جایگزینی رشته ورودی رشته نتیجه
$شماره جایگزینی زیررشته مطابق با شماره گروه. \b(\w+)(\s)(\w+)\b $3$2$1 "یک دو" "دو یک"
${نام} جایگزینی زیررشته مطابق با نام گروه نام. \b(?<word1>\w+)(\s)(?<word2>\w+)\b ${word2} ${word1} "یک دو" "دو یک"
$$ جایگزینی عبارت "$" به صورت حرفی. \b(\d+)\s?USD $$$1 "103 USD" "$103"
$& جایگزینی یک کپی از تمامی مطابقت. (\$*(\d*(\.+\d+)?){1}) **$& "$1.30" "**$1.30**"
$` جایگزینی کل متن رشته ورودی قبل از مطابقت. B+ $` "AABBCC" "AAAACC"
$' جایگزینی کل متن رشته ورودی بعد از مطابقت. B+ $' "AABBCC" "AACCCC"
$+ جایگزینی آخرین گروه تعریف شده. B+(C+) $+ "AABBCCDD" AACCDD
$_ جایگزینی تمام رشته ورودی. B+ $_ "AABBCC" "AAAABBCCCC"

ساختارهای متفرقه


جدول زیر فهرستی از ساختارهای متفرقه را نشان می‌دهد:

ساختار تعریف مثال
(?imnsx-imnsx) تنظیم و یا غیرفعال کردن گزینه‌هایی مانند حساسیت به بزرگی و کوچکی حروف در وسط یک الگو. \bA(?i)b\w+\b با الگوهایی مانند "ABA Able Act" مطابقت می‌کند
(?#توضیحات) نظر خطی. نظر با قرار گرفتن در پرانتز بسته می‌شود. \bA(?#مطابقت با کلماتی که با حرف A شروع می‌شوند)\w+\b
# [تا انتهای خط] نظر حالت X. نظر با شروع با # بدون فرار و ادامه تا انتهای خط است. (?x)\bA\w+\b#مطابقت با کلماتی که با حرف A شروع می‌شوند