نکاتی از رگولار اکسپرشن که شاید ندونید

Regex
Regex

اکثر برنامه‌نویس‌ها تا حدودی با ریجکس آشنا هستند و من نمی‌خوام مقدمات ریجکس رو در اینجا بنویسم. فقط چند تا مورد به درد بخور رو که احتمال می‌دم کمتر شناخته‌شده هستند می‌نویسم.

Word boundry \b

این متاکاراکتر در واقع یه پوزیشن هست و چیزی که باهاش مچ می‌شه طولش صفره. قبل و بعد از کلمات رو مچ می‌کنه (کلمه شامل کاراکترهای [a-bA-B_] می‌شه). کجا به درد می‌خوره؟ وقتی می‌خواید یه کلمه کامل رو پیدا کنید، مثل گزینه Whole Word توی فایند ادیتورها.

/\bis\b/ matchs: This island is beautiful.

توی مثال بالا island مچ نمی‌شه چون بعد از is کلمه تموم نمی‌شه.

Greedy vs lazy

این مورد رو فقط با مثال توضیح می‌دم.

/H.+L/ matchs: HELLO GUYS

توی مثال بالا «نقطه مثبت» تا می‌تونه کاراکترهای بیشتری رو مچ می‌کنه و جلو میره. به این حالت greedy می‌گن.

/H.+?L/ matchs: HELLO GUYS

و تو این مثال «نقطه مثبت علامت سوال» حالت lazy داره و با اولین مچ، کنترل رو میده به مرحله بعدی عبارتمون.

پس وقتی علامت سوال رو اضافه می‌کنیم حالت lazy رو فعال می‌کنیم که دنبال کوتاه‌ترین عبارت می‌گرده و میره سراغ ادامه کار.

Back reference

وقتی چیزی رو داخل پرانتر می‌نویسید و یک گروه می‌سازید می‌تونید به اون گروه در همون عبارت دوباره اشاره کنید، اینطوری:

/<(em|i|b|strong)>.+?<\/\1>/ matches: <em>some text</em> or <b>some text</b>

توی مثال بالا به جای تگ بسته از «بک‌اسلش 1» استفاده کردم که میاد به جاش محتوای پرانتز رو قرار می‌ده. اینطوری تگ‌ها با هم قاطی نمی‌شن و مثلا با این عبارت مچ نمی‌شه:

<strong>some text</b>

اگر دو تا گروه داشته باشید دومی میشه «بک‌اسلش 2» و همینطور تا «بک‌اسلش 9» جا داره.

نکته اینکه اگه از حالت lazy استفاده نمی‌کردیم اون نقطه مثبت تا آخر متن رو بدون توجه به تگ بسته جلو می‌رفت و همه چی به هم می‌ریخت :)

Performance

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

راه حل چیه؟ با تا حد ممکن محدوده تست عبارت رو کوچیک کنیم. «نقطه مثبت» از «نقطه ستاره» بهتره و استفاده از {min, max} از قبلی‌ها بهتر. اگه نوع کاراکترهای مورد نظرتون رو هم می‌دونید اونا رو توی عبارت مشخص کنید. lazy یا greedy بودن لزوما تاثیری نداره.

اگه این مطلب براتون مفید بود خوشحال میشم که با بقیه همرسانش کنید ( ͡ᵔ ͜ʖ ͡ᵔ )