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

تحلیل یک استرینگ !

balabala

کاربر قدیمی پرشین تولز
کاربر قدیمی پرشین تولز
تاریخ عضویت
22 می 2005
نوشته‌ها
8,362
لایک‌ها
5,745
سن
41
محل سکونت
یه خورده اونورتر
من همیشه از این اجق وجقا وحشت داشتم. یجوری جادو میکنن
shock.gif
:دی
 

Shahed

کاربر قدیمی پرشین تولز
تاریخ عضویت
30 ژوئن 2003
نوشته‌ها
7,289
لایک‌ها
34
محل سکونت
mt.cgi
من همیشه از این اجق وجقا وحشت داشتم. یجوری جادو میکنن
shock.gif
:دی
حالا از اون جالبتر الان نیم ساعته من میخوام کدهای firebierd رو برای خودم تحلیل کنم مغرم کرش میکنه وسطش !!
wha[1].gif
 

hossein_asp

کاربر تازه وارد
تاریخ عضویت
31 مارس 2005
نوشته‌ها
639
لایک‌ها
0
سن
39
محل سکونت
جایی که خدا نباشد
من همیشه از این اجق وجقا وحشت داشتم. یجوری جادو میکنن :دی

منم هر وقت میخوام برم سراغش کهیر میزنم :(.

اگر regex خوب و بهینه نوشته بشه. یک خط کد که موتور داخلی PCRE اجرا میکنه و برنامه نویسهای حرفه ای اون رو ساختند به مراتب بیشتر از ده خط کد نوشته شده توسط explode و حلقه و ... زمان میبره. اگر میخوایم بحث رو ببریم اون سمت میشه profile کرد و کدها رو با هم مقایسه کرد.

این حرف من نیست یه جایی خونده بودم اما الان یادم نیست کجا.در این که regex کدش پیجیده تر و بیشتر از حالت عادی کار با رشته است شکی نیست و همچنین حوصله و دانش کسایی که باهاش کار میکنن اما فکر نمیکنم 4 خط کد با توابع ساده php سرعتش و مصرف منابعش بیشتر یا حتی مساوی اون باشه.درسته این یه خطه اما در واقع چندین خط هست.
 

firebird

Registered User
تاریخ عضویت
2 جولای 2005
نوشته‌ها
1,424
لایک‌ها
10
سن
46
من همیشه از این اجق وجقا وحشت داشتم. یجوری جادو میکنن
shock.gif
:دی

حالا از اون جالبتر الان نیم ساعته من میخوام کدهای firebierd رو برای خودم تحلیل کنم مغرم کرش میکنه وسطش !!
wha[1].gif

منم هر وقت میخوام برم سراغش کهیر میزنم :(.

این regex ها رو اینقدر واسه ی خودتون بزرگ نکنید. از خیلی از چیزهایی که الان بلدید ساده تر هستند. فقط اولش رو که مفهوم رو بگیرید بقیه اش راحت هست. اینی که من نوشتم 10-15 ثانیه بیشتر وقت نگرفت. اینجا توضیح میدم ببینید چقدر ساده است

متن ما این بود :
کد:
text1<yek>;text2<do>;text3<se>;text4<chahar>;text5<panj>

ما سه بخش داریم که میخوایم دو بخش رو استخراج کنیم : 1. متن اول (text) که به محض رسیدن به > تموم میشه. 2. بخش دوم که بین <> هست و به محض رسیدن به < تموم میشه. 3. بخش سوم که یا علامت ; هست یا آخر خط هست.

بخش اول در regex با
کد:
([^<]*)
نوشته میشه. هر تعداد کاراکتر هست که به > برسه قطع میشه.
بعد از اون < هست
بعد بخش دوم هست که
کد:
([^>]*)
هست. شبیه بخش اول هست
بعد از اون > هست
آخرین قسمت هم
کد:
(;|$)
هست که یا به ; تطبیق میکنه یا با $ (انتهای رشته). چون از این قسمت استفاده مجدد نمیشه بهتر بود به شکل
کد:
(?:;|$)
مینوشتم که تو حافظه صرفه جویی بشه.

حالا تو متن replacement که همون INSERT ها هست از دو بخش اول و دوم (بین پرانتزها) با استفاده از 1$ و 2$ استفاده میکنیم.
حالا این ساده تر هست و سریعتر نوشته میشه یا حلقه و ... ؟ اگر زمان سنجی کنیم در رشته های بزرگ خواهید دید که این کد سریعتر عمل میکنه.
 

متالیک

کاربر قدیمی پرشین تولز
کاربر قدیمی پرشین تولز
تاریخ عضویت
31 مارس 2007
نوشته‌ها
2,128
لایک‌ها
285
دوست عزیز اسکریپت رو اصلاح کردم و خدمت شما تقدیم می شود:


PHP:
<?php

$str = "text1<yek>;text2<do>;text3<se>;text4<chahar>;text5<panj>";
$str = substr($str, 0, -1);
$str = explode(">;", $str);

foreach ($str as $value) {
 list($arg1,$arg2)=explode("<", $value);
 // your database script goes here! with arg1 and arg2
}

?>



با arg1 و arg2 به راحتی می توانید کار کنید.

موفق باشید
 

متالیک

کاربر قدیمی پرشین تولز
کاربر قدیمی پرشین تولز
تاریخ عضویت
31 مارس 2007
نوشته‌ها
2,128
لایک‌ها
285
کابر عزیز firebird سلام علیکم
ظاهرا اینجا همه با الگو نویسی مشکل دارند و قبلا کار نکردند، اگه می شه یک آموزش خوب و کامل در رابطه با الگو نویسی در php در یک تاپیک دیگه بنویسید تا همه استفاده کنند.
با تشکر فراوان
 

firebird

Registered User
تاریخ عضویت
2 جولای 2005
نوشته‌ها
1,424
لایک‌ها
10
سن
46
کابر عزیز firebird سلام علیکم
ظاهرا اینجا همه با الگو نویسی مشکل دارند و قبلا کار نکردند، اگه می شه یک آموزش خوب و کامل در رابطه با الگو نویسی در php در یک تاپیک دیگه بنویسید تا همه استفاده کنند.
با تشکر فراوان
اینو من خیلی قدیم تو همین فوروم گذاشتم. الان احتمالاً تاپیکش رفته اون ته مها: http://php5.ir/download/regex.zip
 

Shahed

کاربر قدیمی پرشین تولز
تاریخ عضویت
30 ژوئن 2003
نوشته‌ها
7,289
لایک‌ها
34
محل سکونت
mt.cgi
مرسی مرسی خیلی شدید !!
کارم تا حد خیلی زیادی راه افتاد ! اما یه مشکل ! یکم توضیح میدم چی میخوام دقیق !!
راستش این استرینگ رو من از فیلد آدرس دریافت کننده یه اسکریپت وب میل دارم میگیرم !
آدرسهای دریافت کننده ها با ; جدا میشه از هم. و میتونه داخل <> هم باشه. اگه داخل <> باشه اسم گیرنده رو هم کنارش مینویسن. مثلا اینطوری
کد:
کدهای بالا این رو درست اجرا میکنن. یعنی اسم رو میریزن تو متغیر اولی و ایمیل که داخل <> هست توی متغیر دوم که راحت هم میشه اینزرت کردش.
حالا یه مشکلی هست !! الزامی وجود نداره ایمیل ها داخل <> باشن !! میتونن مستقیم ایمیل رو بنویسن !! در این صورت چیزی داخل <> وجود نداره و مقدار متغیر ایمیل null برمیگرده. اما داخل متغیر نام ایمیل برمیگرده !!

چیکار میشه کرد برای این؟
4hba7gi.gif
 

firebird

Registered User
تاریخ عضویت
2 جولای 2005
نوشته‌ها
1,424
لایک‌ها
10
سن
46
اگه همچین رشته ای باشه: کدش میشه
PHP:
$query = preg_replace('/(?<=^|;)\\s*(?:(?:(?P<name>[^;<\\s]*)\\s*<(?P<email>[^>]*)>)|(?P<email>[^;]*));/', "INSERT INTO `table` (`name`, `email`) VALUES ('${name}', '${email}');\\n", $string);
 

Shahed

کاربر قدیمی پرشین تولز
تاریخ عضویت
30 ژوئن 2003
نوشته‌ها
7,289
لایک‌ها
34
محل سکونت
mt.cgi
اگه همچین رشته ای باشه: کدش میشه
PHP:
$query = preg_replace('/(?<=^|;)\\s*(?:(?:(?P<name>[^;<\\s]*)\\s*<(?P<email>[^>]*)>)|(?P<email>[^;]*));/', "INSERT INTO `table` (`name`, `email`) VALUES ('${name}', '${email}');\\n", $string);
کد:
 [B]Warning[/B]: preg_replace() [[URL="http://localhost/mylab/array/function.preg-replace"]function.preg-replace[/URL]]: Compilation failed: two named groups have the same name at offset 68
 

firebird

Registered User
تاریخ عضویت
2 جولای 2005
نوشته‌ها
1,424
لایک‌ها
10
سن
46
کد:
 [B]Warning[/B]: preg_replace() [[URL="http://localhost/mylab/array/function.preg-replace"]function.preg-replace[/URL]]: Compilation failed: two named groups have the same name at offset 68
آره. ایراد داره. دو تا named capture نمیتونن یه اسم داشته باشند.
الان این راه به ذهنم میرسه. شاید راه بهتری هم باشه:
PHP:
$query = preg_replace_callback(
	'/(?<=^|;)\\s*(?:(?:([^;<\\s]*)\\s*<([^>]*)>)|([^;]*));/',
	create_function('$m', 'if ($m[3]) $m[2] = $m[3]; return "INSERT INTO `table` (`name`, `email`) VALUES (\'{$m[1]}\', \'{$m[2]}\');\n";'),
	$string
);
 

Shahed

کاربر قدیمی پرشین تولز
تاریخ عضویت
30 ژوئن 2003
نوشته‌ها
7,289
لایک‌ها
34
محل سکونت
mt.cgi
استاد دمت گرم !!
ولی یه مشکلی دارم من الان. به جای اون insert into میخوام از کلاسی که برای کار با دیتابیس هست استفاده کنم ولی گویا اونتو کار نمیکنه ! یا شاید هم من اشتباه میکنم !
تو این مایه ها هست کلاسم:
PHP:
$dbclass->addemail($email,$name);
 

firebird

Registered User
تاریخ عضویت
2 جولای 2005
نوشته‌ها
1,424
لایک‌ها
10
سن
46
ببین این کار میکنه:
PHP:
$query = preg_replace_callback(
    '/(?<=^|;)\\s*(?:(?:([^;<\\s]*)\\s*<([^>]*)>)|([^;]*));/',
    create_function('$m', '$dbclass->addemail($m[1] , $m[3] ? $m[3] : $m[2]);'),
    $string
);
 

Shahed

کاربر قدیمی پرشین تولز
تاریخ عضویت
30 ژوئن 2003
نوشته‌ها
7,289
لایک‌ها
34
محل سکونت
mt.cgi
کد:
[B][B]Fatal error[/B]: Call to a member function addemail() on a non-object in ...
[/B]
 

Shahed

کاربر قدیمی پرشین تولز
تاریخ عضویت
30 ژوئن 2003
نوشته‌ها
7,289
لایک‌ها
34
محل سکونت
mt.cgi
پوووف !! بیخیال دیگه عذاب وجدان گرفتم !! با همون insert مستقیم کارم رو راه انداختم ! بیخیال کلاس و اینا !! :دی
مرسی firebierd جان. کدت واقعا حرفه ای هست ! :دی کارت درسته :دی
 

firebird

Registered User
تاریخ عضویت
2 جولای 2005
نوشته‌ها
1,424
لایک‌ها
10
سن
46
احتمالاً با این حل بشه :
PHP:
$query = preg_replace_callback(
    '/(?<=^|;)\\s*(?:(?:([^;<\\s]*)\\s*<([^>]*)>)|([^;]*));/',
    create_function('$m', 'global $dbclass; $dbclass->addemail($m[1] , $m[3] ? $m[3] : $m[2]);'),
    $string
);
 
بالا