معالجة السلاسل والتعابير المنتظمة
الجزء الثاني
خامساً: مقدمة عن التعابير المنتظمة:
تدعم لغة PHP أسلوبين لبناء التعابير المنتظمة هما : POSIX Perl
, وهي
قادرة على ترجمتهما كلاهما لكننا سوف نغطي أسلوب POSIX الأبسط هنا.
إن كل عمليات مطابقة
السلاسل التي قمنا بها باستخدام توابع السلاسل كانت مقتصرة على المطابقات الدقيقة
أو مطابقة السلاسل الفرعية بالضبط ، أما إذا كنا نريد أن نقوم بمطابقات معقدة أكثر
مثل مطابقة الأنماط يجب علينا أن نستخدم التعابير المنتظمة التي قد تبدو في
البداية صعبة إلا أنها مفيدة للغاية.
· مفاهيم أساسية:
التعبير المنتظم هو طريقة
لوصف نمط في جزء معين من النص.
المطابقات
الدقيقة التي رأيناها حتى الآن هي شكل من أشكال التعبير المنتظم فالبحث عن الكلمات
“shop” و “delivery” في سلسلة محرفية هو بحث عن تعابير منتظمة.
إن مطابقة التعابير
المنتظمة في PHP مشابه للمطابقة باستخدام
التابع strstr() لأنها تبحث عن تطابق سلسلة ما أو محرف ضمن سلسلة أطول ، فعلى سبيل
المثال السلسلة “shop” تطابق التعبير المنتظم “shop” كما
أنها تطابق التعابير المنتظمة التالية: “h”, “ho” , …. .
يمكن استخدام محارف
خاصة للإشارة إلى المعنى بالإضافة إلى عملية المطابقة ، فعلى سبيل المثال مع
المحارف الخاصة يمكن الإشارة إلى وجود نمط يجب أن يحدث في بداية أو نهاية السلسلة
، أو يمكن تكرار ذلك النمط أكثر من مرة في السلسلة ، أو أن المحارف في هذا النمط
يجب أن تكون من نوع معين ، وكل ذلك سوف يتم بحثه لاحقاً.
· استخدام مجموعات وصفوف المحارف لمقارنة التعابير المنتظمة:
إن استخدام مجموعات وصفوف المحارف في مقارنة
التعابير المنتظمة يعطينا قوة أكبر في المقارنة من استخدام توابع المطابقة التي
رأيناها سابقاً.
يمكن استخدام المحرف (.
) كبديل لأي محرف آخر باستثناء المحرف (\n)
الذي يعبر عن سطر جديد ، فمثلاً التعبير
التالي .at يطابق
أياً من السلاسل التالية:
"cat" و "sat" و "mat" وغيرها من السلاسل التي لها نفس النمط وغالباً
ما نستخدم هذه المطابقة لمقارنة أسماء الملفات في أنظمة التشغيل.
كما يمكننا أن نحدد نوع
المحارف التي نريدها في عملية المطابقة ، ففي المثال السابق التعبير .at يطابق أيضاً التعبير "#at" ، لذا إذا كنا نريد اقتصار عملية المقارنة
فقط على الأحرف بين a و z
عندها نكتب : [a-z]at .
أي شيء محاط بالأقواس
المربعة ([ ]) يسمى character class وهو
يعني صف من المحارف وهو عبارة عن مجموعة المحارف التي سوف تتم المقارنة معها، لكن
يجب الانتباه إلى أن التعبير الموجود ضمن الأقواس المربعة يطابق فقط محرف واحد.
يمكن أن نكتب التعبير [aeiou] والذي يعني أي حرف.
كما يمكن أن
نحدد مجال أو عدة مجالات باستخدام محرف الواصلة (-) ضمن الأقواس المربعة على الشكل التالي:
[a-zA-Z] حيث يحدد هذا التعبير مجالين أي أننا نريد أي
حرف من الحروف الأبجدية وبالشكلين الكبير والصغير.
يمكن أيضًا
استخدام المحرف (^) والذي يعبر عن النفي (فقط ضمن الأقواس المربعة) لنحدد
أننا نريد المطابقة مع المحارف التي ليست موجودة ضمن هذه المجموعة على الشكل
التالي:
[^a-z] أي نريد أي حرف ليس بين a و z
.
هناك مجموعة من صفوف
المحارف المعرفة مسبقاً ضمن الـ PHP
والتي تستخدم لمقارنة التعابير المنتظمة سيتم ذكرها هنا:
-
[[: alnum:]] محارف أبجدية رقمية.
-
[[: alpha:]] محارف
أبجدية.
-
[[: lower:]] أحرف
صغيرة.
-
[[: upper:]] أحرف كبيرة.
-
[[: digit:]] أرقام عشرية.
-
[[: xdigit:]] أرقام سداسية عشرية.
-
[[: punct:]] علامات الترقيم.
-
[[: blank:]] علامات التبويب والمسافات.
-
[[: space:]] محارف المسافة البيضاء.
-
[[: cntrl:]] محارف التحكم.
-
[[: print:]] جميع المحارف القابلة للطباعة.
-
[[: graph:]] جميع المحارف القابلة للطباعة باستثناء المحرف
space.
· التكرار:
في كثير من
الأحيان قد نحتاج (في عملية المطابقة) إلى تحديد وجود تكرارات لبعض السلاسل أو
صفوف المحارف وهنا يمكن أن نستخدم محرفين خاصين لذلك هما :
-
المحرف (*) والذي يعني أنه يمكن تكرار النمط صفر أو أكثر
من المرات.
-
المحرف (+) والذي يعني أنه يمكن تكرار النمط مرة واحدة أو
أكثر من المرات.
ويجب أن نضع
أحد هذين المحرفين مباشرةً بعد جزء التعبير الذي ينطبق عليه ، على الشكل التالي:
+ [[: alnum:]] وهذا يعني أننا نريد "حرف أبجدي رقمي واحد على الأقل".
· التعابير الفرعية:
إن عملية تقسيم تعبير ما إلى تعبيرات فرعية قد
تكون مفيدة في كثير من الأحيان ، وحتى نتمكن من ذلك نستخدم الأقواس على الشكل
التالي:
مثلاً التعبير التالي : (very )*large يطابق التعابير التالية:
"large"
, "very large" , "very very large" and so on
· تكرار التعابير الفرعية:
يمكننا تحديد
عدد مرات تكرار سلسلة ما ضمن تعبير منتظم باستخدام تعبير عددي ضمن الأقواس
المتعرجة ({}) ، حيث يمكن تحديد عدد محدد من التكرارات مثل ({3}) والذي يعني ثلاث مرات بالضبط ، أو مجال من الأعداد مثل ({4 , 2}) والذي يعني من 2 إلى 4 مرات ، أو مجال مفتوح
مثل ({2 , }) والذي يعني على الأقل مرتين.
مثلاً التعبير التالي: (very ){1,
3}
يطابق التعابير التالية:
"very
" , "very very " , "very very very "
· تحديد مكان المطابقة ببداية السلسلة أو نهايتها:
التعبير [a-z] سيتطابق مع أي سلسلة تحتوي على أحرف أبجدية
صغيرة ، فإذا كانت السلسلة طولها محرف واحد أو تحتوي على مطابقة واحدة فقط على طول
السلسلة لا يوجد مشكلة.
أما إذا كنا
هناك أكثر من مطابقة في السلسلة الواحدة نحتاج إلى تحديد مكان المطابقة ضمن
السلسلة مثلاً في البداية أو النهاية أو الوسط.
لذا نستخدم
المحرف (^) في بداية التعبير المنتظم للإشارة إلى أن السلسلة التي نبحث عنها تقع في
البداية ، ونستخدم المحرف ($) في نهاية
التعبير المنتظم للإشارة إلى أن السلسلة التي نبحث عنها تقع في النهاية.
أمثلة :
^bob : هذا التعبير يطابق bob في بداية السلسلة.
com$ : هذا التعبير يطابق com في نهاية السلسلة.
^[a-z]$ : هذا التعبير يطابق سلسلة
تحوي محرف واحد فقط من a
إلى z .
· التفرع:
يمكن أن نعطي عدة
خيارات للمطابقة ضمن التعبير المنتظم ونلك من خلال استخدام المحرف (|).
فمثلاً إذا كنا نريد
المطابقة مع com
أو edu
أو net
نكتب التعبير التالي:
com|edu|net
· مطابقة المحارف الخاصة:
إذا كنت نريد
مطابقة أحد المحارف الخاصة مثل: ( $ . , {
) يجب وضع المحرف (\) قبل المحرف الخاص
ليدل على أننا نريد المحرف بالضبط ولا نريد معناه ، لأن هذه المحارف لها معاني
مختلفة ضمن النظام.
كما أنه إذا أردنا
مطابقة المحرف (\) نفسه نستبدله بخطين على الشكل (\\).
يجب الانتباه إلى وضع
التعابير المنتظمة في لغة PHP ضمن علامات الاقتباس المفردة.
أما إذا كنا نستخدم
علامات الاقتباس المزدوجة مع التعابير المنتظمة ونريد كتابة الخط المائل العكسي
كمحرف ، عندها نحتاج إلى أربعة خطوط مائلة عكسية على الشكل " \\\\ " لأن
مترجم PHP سيقوم بتحليل هذه الخطوط الأربعة على أنها
خطين ومن ثم يقوم مترجم التعابير المنتظمة بتحليل هذين الخطين على أنهما خط واحد.
وبالمثل بالنسبة
للمحرف $ ، فللحصول على المحرف $ ضمن علامات الاقتباس المزدوجة في PHP نحتاج إلى كتابته بالشكل “\\\$”
.
· نظرة عامة على المحارف الخاصة:
-
\ : المحرف المخصص للهروب أو التراجع (Escape) .
-
^ : يستخدم
للمطابقة في بداية السلسلة.
-
$ :
يستخدم للمطابقة في نهاية السلسلة.
-
. : يستخدم للمطابقة مع أي محرف باستثناء المحرف
المعبر عن سطر جديد وهو (\n).
-
| : يستخدم
للإشارة إلى اختيار الخيار البديل (يقرأ كـ OR).
-
) :
يستخدم للتعبير عن بداية نمط فرعي.
-
( : يستخدم للتعبير عن نهاية نمط فرعي.
-
* :
يستخدم للتعبير عن التكرار صفر مرة أو أكثر.
-
+ : يستخدم للتعبير عن التكرار مرة واحدة أو أكثر.
-
{
: يستخدم للتعبير عن بداية كمية.
-
} :
يستخدم للتعبير عن نهاية كمية.
-
؟ :
يستخدم للإشارة إلى أن نمط فرعي ما هو اختياري.
· استخدام التعابير المنتظمة في التطبيق الذكي لشركة بوب:
يوجد على
الأقل استخدامان محتملان للتعابير المنتظمة في التطبيق الذكي Smart Form لشركة بوب.
الاستخدام الأول: هو اكتشاف
مصطلحات معينة في ملاحظات الزبائن فمن خلال استخدام توابع البحث المتعلقة بالسلاسل
يجب إنجاز ثلاث طرق بحث مختلفة للبحث عن التطابق مع الكلمات "shop", "customer" , "service", "retail"
بينما باستخدام
التعابير المنتظمة يمكننا إجراء المطابقة بسهولة أكبر على الشكل التالي:
shop|customer
service|retail
الاستخدام
الثاني: هو التحقق من صحة عناوين البريد الإلكتروني للزبائن في
التطبيق من خلال التنسيق الموحد لعناوين البريد الإلكتروني في التعبير المنتظم ،
حيث يشمل التنسيق بعض الأحرف الأبجدية الرقمية أو علامات الترقيم ، متبوعة برمز @ ،
متبوعًا بسلسلة من الأحرف الأبجدية الرقمية والوصلات ، متبوعة بالنقطة ، متبوعة
بالمزيد من الأحرف الأبجدية الرقمية والوصلات وربما المزيد من النقاط ، حتى نهاية السلسلة
، و بالتالي يكون ترميز عنوان البريد الالكتروني على النحو التالي:
^[a-zA-Z0-9_\-.]+@[a-zA-Z0-9\-]+\.[a-zA-Z0-9\-.]+$
التعبير
المنتظم ^[a-zA-Z0-9_\-.]+ يعني
"بدء السلسلة بحرف أبجدي واحد على الأقل أو رقم أو المحرف ( _ ) أو
(\) أو نقطة أو مزيج من كل ذلك".
نلاحظ أنه
عندما تكون النقطة في بداية عنوان البريد أو آخره فإنها سوف تفقد معناها وتصبح
مجرد نقطة حرفية.
التعبير المنتظم
الفرعي [a-zA-Z0-9\-]+ يطابق الجزء الأول من اسم المضيف ( host name ) بما في ذلك الأحرف الأبجدية الرقمية
والوصلات ، نلاحظ أنه في هذا التعبير لا نضع المحرف ( _ ) لأن له معنى آخر داخل الأقواس المربعة.
التعبير ( \. ) يطابق النقطة الحرفية (.).
التعبير
المنتظم الفرعي [a-zA-Z0-9\-\.]+$ يطابق بقية اسم المجال ( domain name ) بما في ذلك الحروف والأرقام والوصلات والمزيد
من النقاط إذا لزم الأمر ، حتى نهاية السلسلة.
يمكن ظهور عناوين
بريد إلكتروني غير صالحة على الرغم من أنها متطابقة مع التعبير السابق لأنه يكاد
يكون من المستحيل الإمساك بهم جميعًا.
الآن بعد أن تعرفنا
على التعابير المنتظمة سنلقي نظرة على التوابع الموجودة في لغة PHP والتي تستخدم التعابير المنتظمة.
سادساً: التوابع المتعلقة بالتعابير المنتظمة:
· البحث عن سلاسل فرعية ضمن سلسلة ما:
يمكننا استخدام
التعابير المنتظمة للبحث عن سلاسل فرعية ضمن سلاسل أخرى ، ولتحقيق ذلك يتوفر
في لغة PHP التوابع التالية: , ereg() eregi()
·
التابع ereg() له
الشكل العام التالي:
int ereg(string pattern,
string search, array [matches]);
يقوم هذا التابع
بالبحث عن التعبير المنتظم pattern
ضمن السلسلة search ، وفي حال تم العثور على تعبير فرعي من التعبير pattern يتم
وضعه في المصفوفة matches ، بحيث يعبر كل عنصر من هذه المصفوفة عن
تعبير فرعي من التعبير pattern .
·
التابع eregi() مطابق
للتابع السابق مع فرق وحيد أنه غير حساس لحالة الأحرف.
يمكن تعديل نموذج
التطبيق الذكي باستخدام التعابير المنتظمة على الشكل التالي:
if ( ! eregi (‘^[a-zA-Z0-9_\-\.]+@[a-zA-Z0-9\-]+\.[a-zA-Z0-9\-\.]+$’,
$email ) )
{
echo "<p>That is
not a valid email address.</p>".
<p>Please
return to the previous page and try again.</p>";
exit;
}
$toaddress =
“feedback@example.com”; // the default value
if (eregi(“shop|customer service|retail”,
$feedback))
{
$toaddress = “retail@example.com”;
}
else if
(eregi(“deliver|fulfill”, $feedback))
{
$toaddress =
“fulfillment@example.com”;
}
else if
(eregi(“bill|account”, $feedback))
{
$toaddress
= “accounts@example.com”;
}
if
(eregi(“bigcustomer\.com”, $email))
{
$toaddress = “bob@example.com”;
}
· استبدال السلاسل الفرعية ضمن سلسلة ما:
يمكن استخدام التعابير المنتظمة للبحث عن سلاسل
فرعية واستبدالها بأخرى ، وذلك باستخدام التوابع التالية: ereg_replace()
, eregi_replace()
·
التابع ereg_replace() له الشكل العام التالي:
string ereg_replace (string pattern, string replacement, string search);
يقوم هذا التابع بالبحث عن التعبير
المنتظم pattern في
سلسلة البحث search ويستبدلها بالسلسلة replacement .
·
التابع eregi_replace() مطابق للتابع السابق لكن الفرق أنه غير حساس
لحالة الأحرف.
· تقسيم السلاسل:
يمكن استخدام التعابير المنتظمة لتقسيم
السلاسل ، وذلك باستخدام التابع
split()
الذي له الشكل العام التالي:
array split (string pattern , string search , [int max]);
يقوم هذا التابع بتقسيم السلسلة search
إلى سلاسل فرعية بالاعتماد على
التعبير المنتظم pattern
ويعيد السلاسل الفرعية ضمن مصفوفة ، ويشير الوسيط
max إلى أقصى عدد من العناصر يكن أن تصل له
المصفوفة التي يعيدها التابع.
قد يكون هذا التابع مفيد لتقسيم عناوين
البريد الإلكتروني أو أسماء النطاقات أو التواريخ.
مثال على ذلك:
$address = “username@example.com”;
$arr = split (“\.|@”,
$address);
while (list($key, $value) =
each ($arr))
{
echo “<br />”.$value;
}
يقوم هذا الكود بتقسيم عنوان البريد
الالكتروني إلى مكوناته الخمسة ويطبع كل منها على سطر جديد على الشكل التالي:
username
@
example
.
com
تعليقات: 0
إرسال تعليق