PDA

View Full Version : سوال: کمک در تفسیر این regex



desatir7316
یک شنبه 20 اسفند 1391, 17:59 عصر
سلام دوستان
یک قسمت از آموزشی که دارم نگاه می کنم گفته توی regex زیر اون سه تا backslashواسه escape کردن براکته، من یه کم توی regex ضعیفم ولی فک کنم توی آموزش اشتباه می کنه ، برای escape کردن slashباید باشه،
حالا ممنون می شم بگید اون سه تا backslash برای چیه؟

'@[\/\\\]@'

eshpilen
دوشنبه 21 اسفند 1391, 09:04 صبح
رگولار اکسپرشن صحیح است.
البته یخورده گیج کننده هست که حتی بنده هم اول فکر کردم سینتاکسش مشکل داره.
اون سه تا بک اسلش به معنای یک بک اسلش هستن برای انجین رگولار اکسپرشن (و به معنای دو بک اسلش در رشته در سطح PHP).
دو بک اسلش اول، توسط PHP در رشته تبدیل به یک بک اسلش میشن (چون بک اسلش کاراکتر escape کردن در رشته هاست و برای مشخص کردن خودش باید خودش هم escape بشه).
منتها باز یک نکتهء منحرف کننده در این رگولار اکسپرشن اینه که درواقع بک اسلش دوم هم باید توسط دو بک اسلش مشخص میشد، تا در نهایت دو بک اسلش به انجین رگولار اکسپرشن ارسال بشه تا انجین بدونه که منظور، یک کاراکتر بک اسلش بوده. یعنی شما بجای 3 تا میتونی 4 تا بک اسلش هم بذاری!
منتها اینکه بک اسلش آخر بدون escape هم کار میکنه احتمالا بخاطر اینه که کاراکتر بعدش کاراکتری نیست که نیازی به escape کردن داشته باشه (یا شاید دقیقتر این باشه که بگیم یک توالی escape شناخته شده/معتبر در رشته رو تشکیل نمیدن)، و بنابراین PHP اون بک اسلش آخر رو معادل خودش (بک اسلش) قرار میده.
بنظر من بهتره برای رفع ابهام، از چهار بک اسلش استفاده بشه.


<?php

header('content-type: text/plain');

$str='\\';

$patt='@[\/\\\\]@';

preg_match($patt, $str, $matches);

echo '$str: ', "$str\n\n";

echo '$matches: ';

print_r($matches);

?>

در این کد نمونه، شما مقدار متغییر str رو اسلش یا بک اسلش قرار بدی مچ میشه.
البته برای مشخص کردن بک اسلش در رشته باید از دو بک اسلش استفاده کنی.

eshpilen
دوشنبه 21 اسفند 1391, 11:23 صبح
راستی اون اسلش اول هم نیازی به escape کردن نداره (چون در عبارات منظم حاوی معنای خاصی نیست).
یعنی اینم معادل همون کده:

patt='@[/\\\\]@';
منتها اگر بجای @ از اسلش برای محصور کردن عبارت منظم استفاده کرده بودیم، اونوقت مجبور بودیم اسلش رو هم escape کنیم تا با کاراکترهای محصورکننده تداخل نکنه.

desatir7316
دوشنبه 21 اسفند 1391, 12:06 عصر
خیلی مرسی
در کل اون سه تا \\\ برای تشخیص \ هست دیگه درسته؟
توی آموزش گفت که برای براکته!!! برای همین توی شک افتادم

eshpilen
دوشنبه 21 اسفند 1391, 19:00 عصر
در کل اون سه تا \\\ برای تشخیص \ هست دیگه درسته؟
بله.


توی آموزش گفت که برای براکته!!! برای همین توی شک افتادم
برای اینکه براکت رو هم شامل کنید میتونید دو روش استفاده کنید.
روش اول اینکه براکت رو بعنوان اولین کاراکتر داخل [] بذارید. اینطوری انجین رگولار اکسپرشن اون رو بعنوان براکت آخر مجموعه تلقی نمیکنه:

$patt='@[]/\\\\]@';
روش دوم هم اینکه براکت رو با بک اسلش escape کنید:

$patt='@[/\]\\\\]@';
براکت باز (‎[‎) رو هم میشه همینطوری هرجا گذاشت، چون باعث بسته شدن براکت خارجی نمیشه.