Regex (عبارات با قاعده) در کانستراکت - مبحثی مهم و کاربردی
#1
Lightbulb 
به نام خدا
سلام دوستان امیدوارم حالتون خوب باشه...
اگر تجربه کار با زبان های برنامه نویسی مثل PHP، JavaScript، Python و ... رو داشته باشین ممکنه به کلیدواژه Regular Expressions یا Regex (عبارات با قاعده) برخورد کرده باشین. در واقع عبارات با قاعده مجموعه ای از الگوها هستن که در یک یا چند رشته به کار میرن و به ما کمک میکنن که در رشته یا رشته های دلخواه به دنبال الگوهای موردنظر بگردیم و به نوعی ساختار اون رشته ها رو اعتبارسنجی کنیم. به طور مثال فرض کنین قصد دارین یک آدرس مشخص رو از میان لیست هزارتایی آدرس ها استخراج کنین. شما میتونین با استفاده از عبارات با قاعده در کسری از ثانیه با تعیین الگو آدرس موردنظر اون رو استخراج کنین. کاربرد عبارات با قاعده در ژانر بازیهای کلماتی هم به وفور یافت میشه. پس با این تعریفی که ارائه شد در واقع عبارات با قاعده در جایی به کار میرن که در رشته (شامل متن یا اعداد) یک نظم یا الگو خاصی به کار رفته باشه. از نظر بسیاری از افراد استفاده از عبارات با قاعده دشوار به نظر میرسه اما حقیقت اینه که اگر با اصول اونها آشنا بشیم به هیچ وجه مقوله دشواری نیست. 
نحو (سینتکس) در عبارات با قاعده:
برای تعیین کردن الگو موردنظرمون باید با نحو (Syntax) عبارات با قاعده آشنا باشیم. ما در استفاده از دستورات نحوی عبارات با قاعده با پیراینده (Modifier)، متاکاراکتر (Metacharacter)، Quantifier (کمیت سنج) و کاراکترها مواجه میشیم که در ادامه به تشریح هر کدوم از اونها می پردازیم. 
  • * پیرابنده (Modifier): در واقع پیرابنده شامل یک کاراکتر هست که مشخص میکنه جستجو سراسری (Global) باشه (یعنی پس از پیدا شدن اولین نتیجه مرتبط جستجو متوقف نشه و ادامه داشته باشه)، هم چنین مشخص میکنه که نسبت به بزرگی و کوچکی حروف در جستجو حساسیت نشون ندیم و جستجو را در چندین خط انجام دهد. پیرابنده ها عبارتند از:
[تصویر:  table1.png]
  • * کاراکترها: می توان مجموعه ای از کاراکترها (عدد یا حروف و ...) را در یک رشته جستجو کرد و مورد تطبیق قرار داد. کاراکترها عبارتند از:
[تصویر:  table2.png]
  • * Quantifiers (کمیت سنج ها): کمیت سنج ها در واقع مشخص می کنند که یک عنصر (مقدار) مشخص اغلب چند مرتبه روی داده اند یا به وقوع پیوسته اند. کمیت سنج ها عبارتند از:
[تصویر:  table3.png]
  • * مفهوم لفظی (Literal) بودن: تا به اینجای کار با دستورات نحوی مختلفی آشنا شدیم. در این بین قبل از اینکه به ادامه مطالب بپردازیم بهتره با مفهوم دستوری بودن و لفظی (Literal) بودن آشنا بشیم. زمانی دستورات نحوی دستوری تلقی میشن که در کاربردی که براشون تعریف شده به کار برن. زمانی که دستورات نحوی در کاربرد خودشون به کار نرن اصطلاحاً لفظی (Literal) تلقی میشن. به طور مثال زمانی که از دات یا نقطه که راجع به آن کمی جلوتر صحبت خواهیم کرد استفاده می کنیم در واقع مشخص می کنیم که هر عبارتی قابل پذیرش خواهد بود. برای اینکه عبارت دات رو از حالت دستوری خارج کنیم کافیه از یک بک اسلش (\) قبل از دات استفاده کنیم تا معنای لفظی پیدا کنه و دستور تلقی نشه.
  • * متاکاراکترها (Metachracters): 
[تصویر:  tt.png]
  • * مفهوم Wildcard: در بازی های کارتی (مثل پ*و*ک*ر) یک کارت Wildcard میتونه شامل هر مقداری باشه. در دنیای عبارات با قاعده هم همینطوره. عبارت نقطه (.) یا دات میتونه هر کاراکتری رو پذیرش کنه و یک متاکاراکتر به شمار میره. به طور مثال عبارت re.ex نسبت به regex، recex، reDex و ... میتونه واکنش نشون بده. در عبارت بیان شده در واقع با قرار دادن مقدار نقطه می توان هر کاراکتری را در بین دو حرف e مورد تطبیق و پذیرش قرار داد.

حروف خاص در عبارات با قاعده: 
علاوه بر دستورات نحوی معرفی شده یکسری حروف خاص هم در عبارات با قاعده به کار میرن که عبارتند از:
  • * d\ دستور d\ به معنی وجود هر عددی است. در واقع حرف مخفف کلمه Digit به معنی رقم است. 
نکته قابل توجه: کمی قبل تر راجع به کارایی بک اسلش برای تبدیل از حالت دستوری به لفظی صحبت کردیم. اما در حروف خاص بک اسلش چنین کارایی ندارد و کارایی آن برعکس کارایی است که بیان شد. یعنی بک اسلش در اینجا کاراکترهای لفظی را به حالت دستوری تبدیل می کند. همچنین دقت کنید که حروف خاص کوچک و بزرگ می توانند معنای متفاوتی داشته باشند.
  • * D\ دستور D\ به معنی وجود هر کاراکتری که عدد نباشد است. یعنی این حرف خاص تنها کاراکترهای غیر عددی (شامل حروف یا دیگر کاراکترها) را بر می گرداند.
  • * w\ دستور w\ به معنی وجود هر حرف الفبایی انگلیسی کوچک یا بزرگ است. 
  •  W\ دستور W\ به معنی وجود هر حرف الفبایی انگلیسی کوچک یا بزرگ یا عدد نباشد است. به طور مثال اگر این دستور را بر روی رشته P21#W@RR^ اعمال کنیم به ما #، @ و ^ را بر می گرداند.
  • s\ دستور s\ به معنی وجود هر کاراکتری که فضای خالی داشته باشد است.
  • S\ دستور S\ به معنی وجود هر کاراکتری که فضای خالی نداشته باشد است.

ساخت گروه (Grouping) در عبارات با قاعده: 
به کمک پرانتزها () میتونیم توالی از الگوها رو به کمک دستورات ذکر شده تعریف و مشخص کنیم. در واقع با ساخت گروه عبارات با قاعده پیچیده (Complex Regular Expressions) ایجاد می کنیم. عبارات با قاعده پیچیده عبارات با قاعده ای هستن که تنها شامل یک الگو یا دستور نمیشن و همینطور که گفته شد مجموعه ای از الگوها رو شامل میشن. برای ساخت یک عبارت با قاعده پیچیده باید از مفهوم ساخت گروه که با کمک پرانتزها انجام میشه استفاده کنیم. فرض کنین قصد داریم از رشته فرضی image.jpeg کلمه قبل از عبارت .jpg رو استخراج کنیم. برای این منظور عبارت با قاعده ای به شکل زیر مینویسیم:
کد:
([a-z]+[0-9]*)\.jpe?g$
در عبارت با قاعده بالا ابتدا یک گروه به شکل زیر تعریف کردیم:
کد:
([a-z]+[0-9]*)
در این گروه به کمک کمیت سنج * مشخص کردیم که مقادیر عددی یا الفبایی قابل پذیرش خواهند بود. در ادامه عبارت با قاعده داریم:
کد:
\.jpe?g$
به کمک بک اسلش عبارت .jpe را به حالت لفظی تبدیل کردیم و بعد به کمک کمیت سنج وجود کاراکتر e را خنثی یا موثر در نظر گرفتیم. سپس با کمک کمیت سنج مشخص کردیم که انتهای رشته حتماً باید به jpeg یا jpg ختم شود.
استفاده از عبارات با قاعده در کانستراکت:
برای استفاده از عبارات با قاعده در کانستراکت باید از اکسپرشن های سیستمی یا کاندیشن سیستمی Test Regex استفاده کنیم.
  • اکسپرشن RegexMatchAT برای استخراج یک قسمت خاص از رشته با توجه به عبارت با قاعده تعریف شده به کار می رود. این اکسپرشن شامل سه پارامتر String، Regex، Flags و Index است و به شکل زیر به کار می رود:
کد:
RegexMatchAt(String, Regex, Flags, Index)
پارامتر String بیانگر رشته موردنظر جهت پردازش، Regex بیانگر عبارت با قاعده موردنظر، Flags بیانگر پیراینده موردنظر و Index نیز در صورتی که صفر باشد تمامی مقادیر مرتبط یافت شده را بر میگرداند و در صورتی که یک یا بیشتر باشد تنها مقدار یافت شده اولی یا دومی یا ... را بر می گرداند.
  • اکسپرشن RegexMatchCount برای شمارش تعداد دفعاتی که الگو تعریف شده صادق باشد به کار می رود. این اکسپرشن شامل سه پارامتر String، Regex و Flags می باشد و به شکل زیر به کار می رود:
کد:
RegexMatchCount(String, Regex, Flags)
پارامتر String بیانگر رشته موردنظر جهت پردازش، Regex بیانگر عبارت با قاعده موردنظر و Flags بیانگر پیراینده موردنظر می باشد.
​​​​​
  • اکسپرشن RegexReplace برای جایگزین کردن یک رشته دلخواه در یک رشته از پیش تعریف شده با توجه به عبارات با قاعده تعریف شده به کار میرود. این اکسپرشن شامل سه پارامتر String، Regex، Flags و Replace می باشد و به شکل زیر به کار می رود:
کد:
RegexReplace(String, Regex, Flags, Replace)
پارامتر String بیانگر رشته موردنظر جهت پردازش، Regex بیانگر عبارت با قاعده موردنظر، Flags بیانگر پیراینده موردنظر و Replace بیانگر رشته موردنظر جهت جایگزینی می باشد.
  • اکسپرشن RegexSearch در واقع Index یا ایندکس های یافت شده از یک عبارت با قاعده را بر می گرداند. این اکسپرشن شامل سه پارامتر String، Regex و Flags می باشد و به شکل زیر به کار می رود:
کد:
RegexSearch(String, Regex, Flags)
پارامتر String بیانگر رشته موردنظر جهت پردازش، Regex بیانگر عبارت با قاعده موردنظر و Flags بیانگر پیراینده موردنظر می باشد. دقت کنید اگر مقدار موردنظر موجود نباشد مقدار -1 توسط اکسپرشن برگردانده می شود.
  • ​​​​​​​کاندیشن Test Regex بررسی می کند که یک عبارت با قاعده در یک رشته مشخص صادق است یا خیر. در صورتی که عبارت با قاعده صادق (درست) باشد اکشن رو به روی خود را اجرا کرده و در غیر اینصورت اکشن رو به روی خود را اجرا نخواهد کرد. این کاندیشن شامل سه پارامتر String، Regex و Flags می باشد که پارامتر String بیانگر رشته موردنظر جهت پردازش، Regex بیانگر عبارت با قاعده موردنظر و Flags بیانگر پیراینده موردنظر می باشد.

سندرم خلال دندان تکیه داده (Leaning toothpick syndrome یا LTS) : 
به طور کلی هنگامی که یک رشته به قدری شامل کاراکترهای Escaping مثل بک اسلش باشد که خوانش آنها توسط عبارات با قاعده دشوار شود یا دچار اشتباه شود اصطلاحاً می گوییم مشکل LTS یا سندرم خلال دندان تکیه داده داریم. برای رفع این مشکل متأسفانه در کانستراکت مثل زبان های رایج برنامه نویسی راه حل خاصی نداریم و باید خودمون به شخصه پیش بینی حالت های مختلف رو بکنیم و جلوی بروز مشکل LTS رو با استفاده از متاکاراکترهایی مثل [ ^] بگیریم. 
تببین یک مثال جهت فهم بهتر طریقه استفاده از عبارات با قاعده:
فرض کنین قصد داریم به کمک عبارات با قاعده درست بودن ساختار آدرس ایمیل وارد شده توسط کاربر رو بررسی کنیم. برای این منظور کافیه از عبارت با قاعده زیر استفاده کنیم:
کد:
^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$
در عبارت با قاعده بالا به کمک متاکاراکتر مشخص کردیم که آدرس ایمیل موردنظر ما می تواند با حروف و اعداد شروع شود. بعد از عبارت مشخص کردیم که می توان از حروف و اعداد استفاده کرد. در انتها نیز مشخص کردیم که عبارت ما دست کم با دو حرف الفبا چرا که یک دامنه اینترنتی دست کم دو کاراکتر است به پایان برسد. 
همچنین Flag این عبارت با قاعده را نیز gi قرار می دهیم تا هم تمام رشته را جستجو کند (g) و هم نسبت به بزرگی و کوچکی حروف (i) حساسیت به خرج ندهد.
در ایونت زیر ایمیل وارد شده توسط کاربر در یک تکست باکس رو به کمک کاندیشن Test Regex اعتبارسنجی می کنیم و در صورتی که ساختار ایمیل صحیح بود مقدار یک تکست رو به Valid تغییر می دهیم.
[تصویر:  sam.png]
​​​​​​​امیدوارم این مطلب براتون مفید و کاربردی واقع شده باشه.
شاید عبارات با قاعده در نگاه اول دشوار و طاقت فرسا به نظر برسن اما با یک مقدار تمرین و تفکر میفهمین که اتفاقاً هیچ دشواری در این مبحث وجود نداره. بنده سعی کردم در این مطلب یک راهنمای نسبتاً جامع برای استفاده از عبارات با قاعده بنویسم که امیدوارم از پس این کار بر اومده باشم.
در پایان خوشحال میشم نظراتتون رو به بنده گوشزد کنین و اگر جایی اشتباه یا نامفهوم بیان شده حتماً اعلام کنین.
با آرزوی بهترین ها...
غایب
  پاسخ


 سپاس شده توسط: mostafanastary ، mhp ، hasansanaei ، rezamms ، Hamed85 ، kakmamad ، Alireza3d ، محمد 82 ، amin hosseini ، M.gh ، ᔕinaᗪehghani ، oak
#2
ممنون بازم مثل همیشه عالی و کاربردی.
یه سوال فنی(ببخشید نمیدونم جاش اینجا هست یا نه)
اگر بخواهیم تو برنامه ای که با جاوا اسکریپت طراحی کردیم یه کلید به صورت خودکار فشرده بشه چکار باید بکنیم؟
مثلا ما رویداد کیبورد رو نوشتیم . که در صورتی که مثلا کلید a فشرده بشه یه اکشنی رخ بده . 
حالا   تو برخی از لحظات بازی.. این فشرده شدن نمیخواهیم به صورت دستی باشه  و خودکار انجام بشه . همچین امکانی هست؟ 
  پاسخ


 سپاس شده توسط:


موضوع‌های مشابه…
موضوع نویسنده پاسخ بازدید آخرین ارسال
Star مهم آموزش خروجی اندروید روی سیستم شخصی rezamms 127 76,070 1402/8/24، 09:00 عصر
آخرین ارسال: mehdiosw
  مهم آموزش تصویری خروجی مستقیم - یکبار برای همیشه! rezamms 33 17,644 1401/2/13، 09:39 عصر
آخرین ارسال: kamran_cn
  خروجی اندرید davinmstr1 2 2,139 1400/8/4، 10:23 عصر
آخرین ارسال: ᔕinaᗪehghani
  AAB (بسته برنامه اندروید) چيست؟ + نحوه خروجي گرفتن در كرودوا ᔕinaᗪehghani 15 6,988 1400/6/21، 01:55 صبح
آخرین ارسال: mehdi1100
  رفع مشکل خروجی فونگپ (: M.gh 11 7,298 1400/4/10، 02:17 صبح
آخرین ارسال: oak

پرش به انجمن: