PDA

View Full Version : سوال: سوال در مورد escape ها



irpersian20
جمعه 17 مرداد 1393, 02:29 صبح
سلام
راستش من کلی تست کردم و گیج شدم کاملا
ما وقتی @ رو میزنیم یعنی escape ها رو نادیده میگیریم
یعنی

string a1 = "\\\\server\\fileshare\\helloworld.cs";



string a2 = @ "\\server\fileshare\helloworld.cs";



برابر هستند درسته؟
اما اینجا چرا برابر نشدند؟ چرا True میده!

string s = @"\\";


Console.WriteLine(Regex.IsMatch(s, @"\\\\"));


در این حالت رشته یعنی \\ و الگو هم یعنی \\\\\ به خاطر @ . اما این طور نیست! و True میده

یا در این حالت اصلا استثنا پرتاب میشه!
Console.WriteLine(Regex.IsMatch(s, "\\"));
خوب ما از @ استفاده نکردیم و \\ زدیم. یعنی خواستیم فقط \ در اصل چک شود . اما اصلا اجرا نمیشه برنامه :ناراحت:

plus
جمعه 17 مرداد 1393, 03:02 صبح
در مورد اینکه چرا آخری استثنا میده...
Regex خودش Escape مربوط به خودش رو داره، یعنی به عبارتی وقتی رشته ای رو به صورت مستقیم به RegExp میدین، قضیه Escape در Escape میشه.
وقتی "\\" رو به Regex میدین، با توجه به سیستم پردازش رشته توسط #C، رشته حاصل "\" هست و به متد IsMatch داده میشه. حالا RegEx چون خودش Escape داره، "\" خالی براش معنایی نداره و خطا میده.مثلا انتظار "s\" رو داره.
بنابراین اگه بخواین برای RegEx رشته \ رو بفرستین، باید 2 تا \\ بهش بدین و ازونجا که خود #C هم \ براش معنای خاصی داره باید رشته "\\\\" رو به RegEx بدین که با پردازشی که #C میکنه "\\" به RegEx میرسه و با پردازش داخلی RegEx، کاراکتر \ نتیجه نهایی هست و اینطوری دیگه استثنا نمیده...

irpersian20
جمعه 17 مرداد 1393, 09:41 صبح
ممنون واقعا کمک کردید ، گیج شده بودم.
در مورد این مثال:


string s = "\\";


Console.WriteLine(Regex.IsMatch(s, @"\\\\"));

الان دنبال تطبیق این \\ میگرده درسته؟ چون 2 زدیم اولش.پس escape های سی شارپ رو نادیده میگیره و \\ در Regex در نظر میگیره ، صحیح هست؟
فقط آیا راه حلی داره در خروجی بفهمم که دقیقا کدام قسمت تطبیق داده میشود؟(نه کلش بره خروجی-اون قسمت که match شده)
فقط bool بر نگرده.

Mahmoud.Afrad
جمعه 17 مرداد 1393, 10:57 صبح
جناب plus (http://barnamenevis.org/member.php?8256-plus) توضیح دادند.
در مثال پست اول: pattern به صورت \\ در میاد. البته توجه داشته باشید که رشته s هم \\. پس در این مثال فقط یک تطابق بیشتر نداریم.
برای پیدا کردن تطابقها از متد Matches استفاده کن که یک کالکشن برمی گردونه:

string s = @"\\";
MatchCollection mc = Regex.Matches(s, @"\\\\");
foreach (var m in mc)
{
listBox1.Items.Add(m);
}

irpersian20
جمعه 17 مرداد 1393, 11:01 صبح
بله اما الگو ما 2تا بک اسلش هست. درسته؟ یعنی \\
اینجا اصلا تطابقی نداریم.چون رشته ما \ هست و الگو \\ و نتیجه False می باشد.

Mahmoud.Afrad
جمعه 17 مرداد 1393, 11:19 صبح
در مورد مثال پست3 بله تطابق نداریم.

irpersian20
جمعه 17 مرداد 1393, 11:37 صبح
در مورد اینکه چرا آخری استثنا میده...
Regex خودش Escape مربوط به خودش رو داره، یعنی به عبارتی وقتی رشته ای رو به صورت مستقیم به RegExp میدین، قضیه Escape در Escape میشه.
وقتی "\\" رو به Regex میدین، با توجه به سیستم پردازش رشته توسط #C، رشته حاصل "\" هست و به متد IsMatch داده میشه. حالا RegEx چون خودش Escape داره، "\" خالی براش معنایی نداره و خطا میده.مثلا انتظار "s\" رو داره.
بنابراین اگه بخواین برای RegEx رشته \ رو بفرستین، باید 2 تا \\ بهش بدین و ازونجا که خود #C هم \ براش معنای خاصی داره باید رشته "\\\\" رو به RegEx بدین که با پردازشی که #C میکنه "\\" به RegEx میرسه و با پردازش داخلی RegEx، کاراکتر \ نتیجه نهایی هست و اینطوری دیگه استثنا نمیده...

سلام
صحبت شما صحیح ، من میخواهم بدون @ کار رو راه بندازم. الان برای تطبیق / از سه تا استفاده کردم اما باز ارور داره.
Console.WriteLine(Regex.IsMatch(s, "\\\"));
طبق صحبت شما \ برای سی شارپ و \ برای regex و حالا \ رو باید بشناسه.
یعنی \\\ برسیم به \ که اصلا ارور میده!!:افسرده:

حتی این رو ارور میده و پردازش نمیکنه- اصلا معلوم نیست چی به چی هست :ناراحت:
Console.WriteLine(Regex.IsMatch(s, @"\\\"));

Mahmoud.Afrad
جمعه 17 مرداد 1393, 11:57 صبح
اینطوری در نظر بگیر. بدون @ هر دو تا \ توسط کامپایلر سی شارپ تبدیل به یکی میشه. سپس هر دو تا \ در عبارت منظم تبدیل به یک \ میشه.
پس برای تطبیق یک \ باید دوتا \\ در الگو داشته باشیم حالا بدون @ هر کدوم از این دو تا رو باید تبدیل به دو تا کنی. یعنی بدون @ باید چهارتا \ بزاری.

irpersian20
جمعه 17 مرداد 1393, 14:31 عصر
اینطوری در نظر بگیر. بدون @ هر دو تا \ توسط کامپایلر سی شارپ تبدیل به یکی میشه. سپس هر دو تا \ در عبارت منظم تبدیل به یک \ میشه.
پس برای تطبیق یک \ باید دوتا \\ در الگو داشته باشیم حالا بدون @ هر کدوم از این دو تا رو باید تبدیل به دو تا کنی. یعنی بدون @ باید چهارتا \ بزاری.

آقا محمود ممنون از توضیحت
من این رو فهمیدم @\\ وقتی در الگو به کار میره
یعنی escapse های سی شارپ با @ نادیده گرفته میشه و برای \\ به معنی یک بک اسلش در regex هست
اما \\\\ رو نتونستم درک کنم. میخوام واقعا بفهمم چطوری هست؟(وقتی بدون @ دنبال یک بک اسلش بگردیم،باید \\\\ بزنیم.)
خوب \ برای سی شارپ و \ برای ESCAPSE کردن regex حالا \ هم برای خود بک اسلش که میشه 3 تا . نه 4 تا :ناراحت:

plus
جمعه 17 مرداد 1393, 15:50 عصر
دوست عزیز دقیقا حساب دو دو تا چهار تاست. هر دو تا \ در رشته #C میشه یک \ و هر دو تا \ هم در الگوی RegEx میشه یک \. بنابراین شما برای هر رشته ی \ در الگو 4 تا \ باید بدی.
سه تا \\\ توسط #C و خارج از بحث RegEx مشکل داره. "\\\" رو که #C پردازش میکنه، دو تا \ اول رو معادل رشته \ در نظر میگیره، و وقتی به \ بعدی میرسه چون این یک کاراکتر خاص هست و بعدش " هست، "\ رو رو معادل رشته ی " یا همون Double Qutation میگیره و بنابراین چون Quote ی که باید برای انتهای رشته مشخص شده باشه رو پیدا نمیکنه اصلا کد Compile نمیشه.
بنابراین تعداد فرد \ به صورت پست سر هم رو نمیتونید در #C استفاده کنید مگه اینکه برای \ آخر که عمل Escape داره، یک Escape Character تعیین کنید. مثلا "x41\\\" که میشه معادل رشته ی A\

Mahmoud.Afrad
جمعه 17 مرداد 1393, 15:59 عصر
هم زمان نه بلکه لایه ای فرض کن.
اول سی شارپ. پس \\ \\ تبدیل به \\ خواهد شد.
حالا لایه بعد regex هست که \\ به معنی \ خواهد بود.

یا برعکس
یک ESCAPSE در regex داریم پس باید \\ تحویل regex بشه.
حالا هر کدوم از \ ها در سی شارپ یک ESCAPSE پس \\\\ .

یعنی \\\\ بعد از ESCAPSE در سی شارپ میشه \\ که تحویل regex میشه. حالا \\ در regex به معنی \ هست.