• 1
linux web man

الدرس الخامس : السلاسل النصية والتعابير النظامية في لغة php

سؤال

السلام عليكم ورحمة الله وبركاته .

هذا الدرس ضمن سلسة دروس الدورة التالية لتعلم لغة php !

السلاسل النصية والتعابير النظامية :
يمكن تعريف السلسلة النصية انها عبارة عن مجموعة من المحارف يمكن تغيير محتواها بعد انشاءها , حيث تُوفر لغة php دوال متعددة لإجراء مختلف العمليات عليها .

معرفة طول السلسلة النصية :
في كثير من الاحيان عند التعامل مع السلاسل النصية يتوجب علينا معرفة طول السلسة النصية التي نتعامل معها , وللقيام بتلك المهمة نستخدم الدالة strlen التي تعيد طول السلسلة النصية المُمررة اليها , المثال التالي يطبع طول السلسة النصية المخزنة في المتغير string :

<?php$string = 'This is a string';echo strlen($string);// outputs : 16?>


تحويل حالة احرف اللغة الانكليزية :
تقوم الدالة strtolower بتحويل حالة جميع الاحرف الانكليزية الى احرف صغيرة (أي مثلاُ تقوم باستبدال A بالحرف a) , وتفيد هذه الدالة على سبيل المثال عند تسجيل المستخدم في الموقع حيث نقوم بجعل جميع احرف المُعرف صغيرة حتى لا يكون لدينا مستخدمَين بنفس المُعرف .
تقبل هذه الدالة وسيطا وحيداً هو السلسة النصية وتُعيد سلسلة نصية يكون فيها جميع الاحرف بالحالة الصغيرة :

<?php$string = 'This Is A sTrIng 123';echo strtolower($string);// outputs : this is a string 123?>

ويوجد هناك الدالة strtoupper التي تقبل نفس وسائط الدالة السابقة لكنها تحول حالة الاحرف الى احرف كبيرة :
 

<?php$string = 'This Is A sTrIng 123';echo strtoupper($string);// outputs : THIS IS A STRING 123?>


لاحظ ان الارقام أوالاحرف العربية لا تتأثر بهاتين الدالتين .

استبدال نص :
عند الحاجة لاستبدال عبارة بعبارة اخرى , نستخدم الدالة str_replace التي يكون شكلها العام كالتالي :

str_replace($search, $replace, $string);

تقبل هذه الدالة ثلاث وسطاء اجباريين : الاول هو النص المراد البحث عنه ويمكن ان يكون نوع هذا المتغير سلسة نصية أو مصفوفة كما سنرى في الامثلة , والوسيط الثاني هو النص المراد استبدال النص السابق وكما في الوسيط السابق يمكن ان يكون نص أو مصفوفة , أما الوسيط الثالث فيكون السلسلة النصية التي ستجرى عليها عملية الاستبدال .
تُعيد الدالة السابقة سلسة نصية تحوي على النص المُعدل . لازالة ما حصل من غموض جرب الامثلة التالية :

<?php$string = 'this is a long string !!';$new_string = str_replace('long', 'short', $string);echo "The first string is : $string <br>";echo "The replaced string is : $new_string";?>

في المثال السابق قمنا باستبدال الكلمة long الموجودة في السلسلة النصية الاولى بالكلمة short وقمنا بتخزين السلسلة النصية الناتجة في المتغير new_string .

<?php$string = 'this is a long string !!';$new_string = str_replace(array('this', 'long', '!!'), array('This', 'short'), $string);echo "The first string is : $string <br>";echo "The replaced string is : $new_string";?>

في هذا المثال قمنا بجعل الوسيطين الاول والثاني مصفوفات حيث يتم استبدال العناصر بالترتيب , ولكن - كما تلاحظ - فإن المصفوفة الاولى تحوي على العنصر الذي قيمته "!!" بدون وجود نظير له في المصفوفة الثانية مما يؤدي الى استبدال هذه القيمة بقيمة فارغة , المثال السابق سيعطي الخرج التالي :
The first string is : this is a long string !!
The replaced string is : This is a short string

يجدر بالذكر بأن الدالة str_ireplace تعمل نفس عمل الدالة str_replace لكنها غير حساسة لحالة الاحرف .

ازالة وسوم HTML :
تقوم الدالة htmlentities باستبدال وسوم لغة HTML بمكافئاتها من ما يسمى html entities . فمثلا الرمز ">" يُستبدل ب "<" و الرمز "&" يُستبدل بـ "&" , و تُستخدم هذه الدالة لفلترة النصوص التي يقوم بادخالها المستخدم فمثلا ً : اذا ادخل المستخدم اسمه على الشكل التالي "<b>username</b>" فسيتم اظهار الاسم بخط عريض لكن عند استخدام الدالة htmlentities فسيتم اظهار الاسم كما تمت كتابته , المثال التالي يوضح ذلك :

<?php$username = '<b>Abd Allatif</b>';echo 'The user name without using htmlentities function : '.$username;echo '<br>';echo 'The user name when using htmlentities function : '.  htmlentities($username);?>

اما الدالة htmlspecialchars فتقوم بنفس عمل الدالة  htmlentities إلا انها تقوم بتحويل محارف خاصة محددة , وكلا الدالتين يقوم بتحويل علامات الاقتباس المزدوجة الى "

 

وتتركان علامات الاقتباس المفردة دون تغيير ولاجبارهم على تحويلها الى html entities نستخدم الراية ENT_QUOTES كوسيط ثان , أما عند استخدام الراية ENT_NOQUOTE فلن يتم استبدالهما .

فيكون الفرق الجوهري بين الدالتين, أن الأولى "htmlentities" ستقوم بتحويل كل محرف قابل للتحويل إلى نظيره من الـ html entities, أما الدالة الثانية "htmlspecialchars" فهي متخصصة في محارف الخاصة محددة فقط, كـ & و " و < و > و ( ' ولكن فقط عندما يكون الوسيط ENT_QUOTES ممرراً كما تم الإشارة سابقاً) 

 

لإزالة الغموض جرب المثال التالي :

<?phpheader('Content-Type: text/html; charset=utf-8');$string = '"السلام عليكم"';echo htmlspecialchars($string, ENT_NOQUOTES);echo '<br>';echo htmlentities($string);?>

لذا من المُفضل في الحالة العامة ولهدف الحماية من بعض هجمات XSS استخدام الدالة htmlspecialchars . وتوجد دالة باسم strip_tags تقوم بازالة جميع وسوم HTML.


التعابير النظامية Regular Expression :

التعابير النظامية هي عبارة عن طريقة لكي نستطيع مطابقة نص معقد بواسطة عدد من المحارف والرموز ذات الدلالات الخاصة مثل *.؟ ...الخ , حيث توفر لغة php كما في سائر لغات البرمجة امكانية البحث و استبدال النصوص بواسطة التعابير النظامية .
في السابق كانت لغة php تُوفر طريقتين لمعالجة نوعين من التعابير النظامية الاولى هي POSIX والثانية هي التعابير النظامية الخاصة بلغة perl , لكن لغة php قامت بازالة POSIX في الاصدار  5.3.0 لذا لن يتم التطرق لها .

انشاء عبارات التعبير النظامية :
يجب بدء عبارة التعبير النظامي يالرمز "/" ويجدب انهاءه بنفس الرمز , اقواس المحموعة [] تستخدم لتحديد عدد معين من المحارف (حروف أو ارقام أو رموز) مثلا : النمط [abc] يطابق a أو b أو c , أما النمط [a-z] فيطابق جميع الاحرف الانكليزية الصغيرة وايضا النمط [a-zA-Z0-9] يطابق جميع الاحرف الانكليزية بحالتيها (احرف كبيرة واحرف صغيرة) والارقام من 0 الى 9. اما لو أضفنا الرمز ^ بعد فتح قوس المجوعة فهو يشير الى عدم مطابقة مجموعة الاحرف التالية مثلا : [^a] لا يطابق الحرف a , ولكل رمز معنى خاص في التعابير النظامية موجودة في الجدول التالي :
* المحرف "." يطابق أي محرف باستثناء محرف السطر الجديد "\n"
* المحرف "؟" يطابق تكرار النمط 0 أو 1 مرة
* المحرف "*" يطابق تكرار النمط 0 مرة أو أكثر
* المحرف "+" يطابق تكرار النمط 1 مرة أو أكثر
* التعبير {x} يطابق تكرار النمط x مرة
* التعبير {x , y} يطابق تكرار النمط x مرة على الاقل و y مرة على الاكثر


واذا اردت ان تقوم بمطابقة أي رمز من الرموز السابقة نستخدم رمز "/" قبلها .

ويوجد عدد اخر من المعرفات يمكن استخدامها في التعابير النظامية فمثلا بدلا من استخدام النمط [0-9] نقوم باستخدام  المُعرف \d والجدول التالي يوضح اهم المعرفات :
* المُعرف d\ يطابق أي رقم
* المُعرف D\ يطابق أي محرف باستثناء الأرقام
* المُعرف  s\ يطابق المحرف الذي يمثل فراغ " "
* المُعرف S\ يطابق أي محرف باسثناء الفراغات
* المُعرف ^ يطابق بداية السطر
* المُعرف $ يطابق نهاية السطر
* المُعرف w\ يطابق أي حروف أو ارقام


لتفادي اللبس , المحرف ^ يطابق بداية السطر فقط اذا كان خارج أي نمط فرعي .
أمثلة عن كتابة انماط للتعابير النظامية :
اذا اردنا مطابقة تاريخ ما وكان هذا التاريخ مكتوب بضيغة "YYYY-MM-DD" فيمكن بكل سهولة مطابقته بواسطة النمط التالي :

/(\d{4})-(\d{1,2})-(\d{1,2})/

في النمط السابق يوجد ثلاث انماط فرعية حيث يفصل بينها - وكل نمط فرعي يجب ان يكون فقط رقم وذلك بتحديد \d ومن ثم تحديد عدد تكرارات كل منها .
مثال اخر : مطابقة عنوان بريد الكتروني : يكون البريد الالكتروني عادة من الشكل :
[email protected]
[email protected]
[email protected]
[email protected]_mple.com

ولمطابقة جميع الحالات يمكن استخدام النمط التالي :

/^([a-zA-Z0-9_])[email protected]([a-zA-Z0-9_])+(\.[a-zA-Z0-9_]+)+$/

النمط السابق معقد نسبيا , في البداية استخدمنا النمط ([a-zA-Z0-9_])+ الذي يطابق اي حرف من اللغة الانكليزية بالإضافة الى الارقام والشرطة السفلية _ , واشاردة + تدل على تكرار هذا النمط مرة أو اكثر , ومن ثم وضعنا الاشارة @ وبعدها تكرار لنفس النمط الفرعي السابق , وفي النهاية قمنا بمطابقة رمز النقطة (لا تنسى وضع الشرطة المائلة \ قبلها) ومن ثم النمط الفرعي السابق مع الانتباه الى اشارة + الثانية التي تسمح بوجود "مجالين" مثلا ".gov.sa" ولاحظ ايضا اننا بدأنا النمط باستخدام ^ وقمنا بإنهاءه باستخدام $ .

دوال التعامل مع التعابير النظامية :

البحث عن نمط :
وذلك بواسطة الدالة preg_match حيث تقوم هذه الدالة بالبحث عن نمط للتعابير النظامية داخل سلسلة نصية , تُعيد هذه الدالة true في حال وجود مطابقة و false عدا ذلك , شكل الدالة العام :

preg_match($pattern, $subject‬‬ , [$array_matches]);

كما هو واضح , الوسيط الاول هو النمط الخاص بالتعابير النطامية و الوسيط الثاني هو السلسلة النصية التي سيتم البحث فيها أما الوسيط الثالث فهو اسم متغير المصفوفة التي سيتم تخزين نتائج المطابقة فيها وسيتم الحديث عنها لاحقا .
الان لنجرب النمط السابق الذي يقوم بمطابقة تاريخ من الشكل : "YYYY-MM-DD"

<?php$reg = '/(\d{4})-(\d{1,2})-(\d{1,2})/';$date1 = '1995-5-21';$date2 = '95-May-21';if(preg_match($reg, $date1) != false){    echo "Date '$date1' is a valid Date";}else{    echo "Date '$date1' is a NOT valid Date";}echo '<br>';if(preg_match($reg, $date2) != false){    echo "Date '$date2' is a valid Date";}else{    echo "Date '$date2' is a NOT valid Date";}?>

الوسيط الثالث عند تحديده يقوم بانشاء مصفوفة حيث يكون العنصر الاول فيها (مفتاحه 0) يحوي الجملة التي تمت مطابقتها , اما بقية العناصر فتمثل الانماط الفرعية بالترتيب , فمثلا لنقم بتعديل المثال السابق كي نستطيع استخراج السنة و الشهر و التاريخ :

<?php$reg = '/(\d{4})-(\d{1,2})-(\d{1,2})/';$date = '1995-5-21';if(preg_match($reg, $date, $results) != false){    echo "Date '$date' is a valid Date";    echo '<br>';    echo "The full match is {$results[0]} <br>";    echo "The Year is {$results[1]} <br>";    echo "The Month is {$results[2]} <br>";    echo "The Day is {$results[3]}";}else{    echo "Date '$date' is a NOT valid Date";}/*Date '1995-5-21' is a valid DateThe full match is 1995-5-21The Year is 1995The Month is 5The Day is 21*/?>

الدالة preg_repalce :
تقوم هذه الدالة باستبدال نص بنص اخر بالإعتماد على التعابير النظامية ويكون شكلها العام كالتالي :

preg_replace($pattern, $replacement, $subject‬‬);

ويوجد طريقتين لإستدعاء هذه الدالة : الطريقة الاولى أن تكون$replacement , $patternمصفوفات حيث يتم استبدال كل نمط محدد بعنصر من المصفوفة pattern بنص مقابل له من المصفوفة replacement . وأما الطريقة الثانية فتكون فيها $replacement , $pattern  سلسلتان نصيتان . المثال التالي يقوم بتحويل التاريخ من الشكل "YYYY-MM-DD" الى الشكل "DD|MM|YYYY" :

<?php$reg = '/(\d{4})-(\d{1,2})-(\d{1,2})/';$replace = '$3|$2|$1';\\$0 represents the complete match , $1 the first sub-pattern , $2 the second sub-pattern ... etc.echo preg_replace($reg, $replace, '1995-5-21');?>

في النهاية , موضوع التعابير النظامية موضوع كبير و متشعب ولا يمكن اختصاره ببضعة اسطر حيث يوجد هناك كتب كاملة تتحدث عنهم ككتاب Mastering Regular Expressions

وايضا على php.net

 

تمرين

قم بانشاء نمط للتحقق من صحة روابط من الشكل :

http://www.example.com/.....
https://www.example.net/....,
http://example.com

4

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

2 إجابة على هذا السؤال .

  • 0

جميل جدا بارك الله بك  :)

وفقك الله و الأخ أحمد سعود لكل خير

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

السلام عليكم

 

بارك الله فيك عبداللطيف على هذا الدرس الرائع , ولا غنى لمن يريد كتابة تطبيقات قوية عنه , سلمت يداك

 

وهذا كتاب بالعربية لأحد الزملاء

regex.pdf

 

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

من فضلك سجل دخول لتتمكن من التعليق

ستتمكن من اضافه تعليقات بعد التسجيل



سجل دخولك الان

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .