[ اللهمَّ عَلِّمْنا ما يَنْفَعُنا وانْفَعْنا بِمَا عَلَّمْتَنا وَزِدْنَا عِلْماً يَا رَبَّ الْعَاْلَمِين ]
هذا الموضوع مشاركة بسيطة مني لكم ، وأعتبرها نقطة مقابل بحر من الأفضال التي قدمها لي سوالف ...
بداية أحب أذكر فقط أن هذا الجزء من الــ php بالذات استغرق معي قرابة الأسبوع من الدراسة ، حتى أتقنت معظم جوانبه بحمد الله .
قد أسهو في هذه المقالة نسبة لعدم تركيزي الآن على هذا الجانب من php الآن واهتمامي بلغات أخرى ...
أثناء تجوالي على دروس التعابير القياسية في المنتدى ، لاحظت أن معظم الدروس والمقالات تحدث عن Matching Functions أو دوال المطابقة بأنواعها : ereg , eregi , preg_match , preg_match_all
حيث تركزت الدروس على هذه الدوال بصورة عامة ، وما ذكر عن بقية أنواع التعابير القياسية ورد ضمن أمثلة البعض دون الإشارة إلى ما تعنيه .
كذلك أهملت الدروس والمشاركات الإشارة إلى المعدلات أو ما يعرف باسم الــ modifiers والتي سأفرد لها مقالة خاصة بإذن الله .
تعتبر التعابير القياسية إحدى أقوى أدوات الـphp في مجاراة النص والتحكم به ومعالجته بشتى أناوع الطرق .. حيث توفر له أسهل الطرق لتعديل أو استخراج أو استبدال كل أو جزء من النص .
المتابع لتطور هذا الجزء من php يلاحظ نوعين من الدوال ereg و perg حيث الأولى التقليدية تولدت مع php ولكن الثانية تمثل أحد التطويرات التي طرأت في كجال التعابير القياسية ، للمعلومية فقط دوالpreg أسرع من دوال ereg ، فقط تعتبر ereg محبوبة من قبل المبرمجين لطول عهدهم معها ،، ،
أحد الفروقات بين الدالتين يتمثل في اشتراط تضمين محددات البداية والنهاية // أو @@ أو غيرها ...
كود PHP:
eregi('pattern', 'string');
preg_match('/pattern/', 'string');
من حظنا أن تتمتع لغة php بهذه الخاصية التي تساعد أيضا في تحرير أكواد html وكذلك الــ tags وغيرها بصورة سريعة ومنظمة ,,,
"*" تنقسم التعابير القياسية بصورة عامة إلى 3 أقسام :
1 - دوال تعابير المطابقة Matching Functions
2 - دوال تعابير الإستبدال أو الإحلال Replacement functions
3 - دوال تعابير تقسيم النص Splitting functions
أولا :
- دوال تعابير المطابقة Matching Functions
لن أتحدث عنها فقد أخذت الجانب الأكبر من مواضيع التعابير القياسية في المنتدى .
ثانيا :
- دوال تعابير الإستبدال أو الإحلال Replacement functions
تستخدم هذه التعابير لإستبدال السلاسل النصية المتطابقة وفقا للنمط بسلاسل نصية أخرى .
لهذه التعابير
#دوال الإحلال .
#1
الدالة :
كود PHP:
preg_replace ($pattern,$replacement,$handle,$arrayname)
تحتاج هذه الدالة لأربع بارمترات ،
الثلاث الأوائل منها إجبارية .
وهي على النحو التالي :
كود PHP:
$pattern = النمط المطلوب إيجاده
$replacement = صيغة الإستبدال
$handle = مقبض النص أو النص المراد البحث فيه .
تقوم هذه الدالة بإرجاع قيم الأقواس العادية كما هي زذلك للإستفادة منها ،
حيث تشير لكل قوس على الترتيب بــ:
كود PHP:
\\1 للقوس الأول
\\2 للقوس الثاني
بينما طريقة عمل هذه الدالة هي :
تقوم الدالة بمطابقة النمط وعند الأنتهاء من المطابقة تقوم باللإنتقال إلى صيغة الإستبدال ..
فتستبدل الدالة كل ما هو خارج عن الأقواس العادية بالنص المطلوب استبداله وتعيد قيمة ما بداخل الأقواس باستخدام المراجع .
ملحوظة :
يمكن استخدام $ بدلا من \\ .
-- ما سبق كان للنصوص المحددة بالإقتباس الفردي ' ' .
بينما تتحول \\ في الإقتباس المزدوج إلى \\\\ ، أو تكتب $ مسبوقة بــ\ في حالة استخدام علامة الدولار هذه .
لذلك دائما ما يتجه و يميل المبرمجون إلى استخدام الأقواس الفردية حتى يتجنبوا " مضايقة مترجم PHP بالبحث و اعتباره لمعاني أخرى لبعض العلامات " ، وهي واحدة من أساليب القياسية في كتابة الشفرات .
كذلك نجد أن العنصر الأول المشارله بــ 0 في مصفوفة النواتج يحتوي على التطابق التام لصيغة الإستبدال ، شأنه شأن العنصر نفسه في تعابير المطابقة Matching Functions .
باختصار نبحث عن النص المراد استبداله ونحتفظ بالأجزاء التي لا يراد استبدالها في الأقواس ونضعها ضمن صيغة الإستبدال .
لاحظ المثال :
كود PHP:
<?php
$str = '[link url="http://swalif.com"]swalif[/link] is good refrence for developer and programmer.';
$pattern = '@\[link\ url="([^"]+)"\](.*?)\[/link\]@';
$replacement = '<a href="\\1">\\2</a>';
$str = preg_replace($pattern, $replacement, $str);
echo $str;
?>
المخرجات هي :
كود PHP:
<a href="http://swalif.com">swalif</a> is good refrence for developer and programmer.
لاحظ استبدلنا
عن طريق الصيغة
بينما أخذنا الرابط
كود PHP:
[url]http://swalif.com[/url]
بواسطة القوس
وأخذ تلقائيا المرجع \\1
كذلك أخذنا الكلمة المراد ظهور الرابط النشط من خلالها وهي swalif بالقوس
وذلك حتى نضعها كما هي في الرابط الجديد
وقمنا باستبدال
بواسطة النمط
بينما ظلت is good refrence for developer and programmer. كما هي في الرابط الأول والثاني .
حقيقة قد يتسائل البعض هل هذا استبدال في الحقيقة أم استخلاص ...
وللعدل نقول أننا نستخلص ما نريد من الرابط الأول بواسطة النمط الثانوي
ونشير للنمط الثانوي بمراجعه في الباراميتر الثالث فقط ...
ملحوظة:
- يطلق على الأقواس الأنماط الثانوية .
يمكن أيضا أن تقوم الدالة preg_replace باستبدال أكثر من سلسة نصية وذلك عند تعاملها مع الباراميتر الثالث عندما يكون مصفوفة .
لاحظ المثال جيدا :
اتبعت فقط طريقة كتابة الأسماء في اللغات الأجنبية ، حيث يأتي اسم الوالد قبل اسم الولد
سنقوم في كل عنصر من عناصر المصفوفة بتبديل الإسم قبل الفاصلة بالإسم الذي بعدها ونجعلها اسما واحدا .
كود PHP:
<?php
$names = array(
'matar,ahmed',
'shogy, ahmed',
'henry, terry'
);
$names = preg_replace('@([^,]+).\ (.*)@', '\\2 \\1', $names);
?>
ستكون المخرجات كالتالي :
كود PHP:
array('ahmed matar', 'ahmed shogy', 'terry henry');
مثال آخر :
كود PHP:
<?php
$names = array(
'matar, ahmed',
'shogy, ahmed',
'henry, terry'
);
$names = preg_replace('@([^,]+).\ (.*)@e', 'ucwords("\\2 \\1")',$names);
print '<pre>';
print_r($names);
print '</pre>';
?>
لاحظ أن المخرجات على الشكل التالي :
كود PHP:
Array
(
[0] => Ahmed Matar
[1] => Ahmed Shogy
[2] => Terry Henry
)
لاحظ استخمنا المعدل e وهو أحد المعدلات modifiers التي تستخدم فقط مع تعابير اللإستبدال .
ملحوظة صغيرة : تضاف الــmodifiers بعد علامة \ أو @ الأخيرة في النمط .
* ستكون هناك مقالة عن المعدلات واستخدامتها ...لاحقا .
نفس المثال بدون استخدام المعدل e والدالة ucwords
كود PHP:
<?php
$names = array(
'matar, ahmed',
'shogy, ahmed',
'henry, terry'
);
$names = preg_replace('@([^,]+).\ (.*)@', '("\\2 \\1")',$names);
print '<pre>';
print_r($names);
print '</pre>';
?>
والمخرجات :
كود PHP:
Array
(
[0] => ("ahmed matar")
[1] => ("ahmed shogy")
[2] => ("terry henry")
)
نفس المثال باستخدام المعدل e فقط .
كود PHP:
<?php
$names = array(
'matar, ahmed',
'shogy, ahmed',
'henry, terry'
);
$names = preg_replace('@([^,]+).\ (.*)@e', '("\\2 \\1")',$names);
print '<pre>';
print_r($names);
print '</pre>';
?>
والمخرجات هي :
كود PHP:
Array
(
[0] => ahmed matar
[1] => ahmed shogy
[2] => terry henry
)
* لن أخوض في الحديث عن الــmodifiers لكن من النظر إلى الصيغ المختلفة للنتائج أعتقد أنك عرفت فائدة المعدل e .
الدالة
كود PHP:
preg_replace_callback
تستخدم في استدعاء التعابير البديلة من الدوال functions
مثلا:
كود PHP:
<?php
function format_string($matches)
{
return ucwords("{$matches[2]} {$matches[1]}");
}
$names = array(
'matar, ahmed',
'shogy, ahmed',
'henry, terry'
);
$names = preg_replace_callback(
'@([^,]+).\ (.*)@', // النمط
'format_string', //استدعاء الدالة
$names // مصفوفة النتائج
);
print "<pre>";
print_r($names);
print "</pre>";
?>
والمخرجات :
كود PHP:
Array
(
[0] => Ahmed Matar
[1] => Ahmed Shogy
[2] => Terry Henry
)
لاحظ لو استخدمنا في المثال السابق الدالة
لكانت المخرجات
كود PHP:
Array
(
[0] => format_string
[1] => format_string
[2] => format_string
)
لن يحصل استدعاء للدالة .... وهذه نقطة من نقاط الفروقات بين الدالتين .
مثال مختلف يوضح أن الدالتين يمكنهما أن تمرران النمط كمصفوفة ، و
كود PHP:
<?php
$text = "Sara is a nice girl; she is very pretty AND so clever";
$patterns = array('@[A-Z]@e', '@[\W]@', '@_+@');
$replacements = array('strtolower(\\0)', '_', '_');
$text = preg_replace($patterns, $replacements, $text);
echo $text."\n";
?>
والمخرجات كالتالي :
كود PHP:
sara_is_a_nice_girl_she_is_very_pretty_and_so_clever
ثالثا :
- دوال تعابير تقسيم النص Splitting functions :
ستفاد منها في تقسيم النص إلى أجزاء متعددة ، مثل معرفة عدد الكلمات في جملة ، وغير ذلك من الوظائف .
دوال تقسيم النص :
1- preg_split
تحتاج هذه الدالة لأربع بارامترات
كود PHP:
preg_split('@pattern@', $arraynamer, 123, type);
//pattern = النمط المطلوب
//$arrayname = مصفوفة النواتج
//123 = رقم يحدد عدد مرات التقسيم المطلوبة قبل التوقفات المنفصلة للدالة
// type = نمط تقسيم فرعي
البارمتران الثالث والرابع اختياريان وليسا اجباريان لكنهما يستخدمان بكثرة .
مثلا :
كود PHP:
<?php
$str = 'I am a member in swalif.';
$words = preg_split('@[\W]+@', $str, 3);
print'<pre>';
print_r($words);
print'</pre>';
?>
والمخرجات هي :
كود PHP:
Array
(
[0] => I
[1] => am
[2] => a member in swalif.
)
تم تقسيم النص إلى 3 أقسام ....
بناء على العدد المطلوب في الباراميتر الثالث
* ملحوظة /
الباراميتر الثالث إذا لم يكتب سيتم تقسيم النص جميعه فقط سيكون العنصر الأخير في المصفوفة عنصر فارغ ، لاحظ المثال :
كود PHP:
<?php
$str = 'I am a member in swalif.';
$words = preg_split('@[\W]+@', $str);
print'<pre>';
print_r($words);
print'</pre>';
?>
والمخرجات :
كود PHP:
Array
(
[0] => I
[1] => am
[2] => a
[3] => member
[4] => in
[5] => swalif
[6] =>
)
قد يتساءل البعض عن كيفية التخلص من العنصر الفارغ ،" لا يأتي أحد ويقول لي أن يحدد العدد في البارميتر الثالث " لأنه لن تكون هناك فائدة من استخدام الدالة ، ، ،
لكن لا تخف php تعاملت مع هذه النقطة بالذات بإجراءات سهلة جديدة بتطويع البارمتر الرابع.,.,
لدينا ثلاث طرق من النظر فقط سوف تعرف فائدة هذه الطرق ، لاحظ جيدا :-
# أ
PREG_SPLIT_NO_EMPTY
تمنع وجود عناصر فارغة في نهاية المصفوفة ،
مثال:
كود PHP:
<?php
$str = 'We are muslims';
$words = preg_split('@[\W]+@', $str, -1, PREG_SPLIT_NO_EMPTY);
print'<pre>';
print_r($words);
print'</pre>';
?>
المخرجات :
كود PHP:
Array
(
[0] => We
[1] => are
[2] => muslims
)
# ب
PREG_SPLIT_DELIM_CAPTURE
تعود بالعنصر المحدد نفسه ،كذلك تعتبر هذه الدالة المسافة بين الكلمات عنصرا من عناصر المصفوفة وكذلك علامات الترقيم ، وتستخدم مع PREG_SPLIT_NO_EMPTY في نفس خانة الــtype مع وضع العلاقة المناسبة بينهما ، ركز في المثال بصورة جيدة :
كود PHP:
<?php
$str = 'We are muslims.';
$words = preg_split(
'@([\W]+)@', $str, -1,
PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY
);
print'<pre>';
print_r($words);
print'</pre>';
?>
المخرجات :
كود PHP:
Array
(
[0] => We
[1] =>
[2] => are
[3] =>
[4] => muslims
[5] => .
)
# ج
PREG_SPLIT_OFFSET_CAPTURE
تعود بمصفوفة ثنائية الأبعاد تحتوي على العنصر و مفتاحه ،،، " حقيقة لم أستخدمها أبدا أثناء تعاملي مع لغة php " و أطلب من أصحاب الدراية بهذه الفقرة أن يتفضلوا بطرح أفكارها وا ستخداماتها ..
تحصلت على المثال في مشاركة في أحد المنتديات الأجنبية " لا تسألوني عشان لا أجيب العيد" :
كود PHP:
<?php
$str = 'This is an example.';
$words = preg_split(
'@([\W]+)@', $str, -1,
PREG_SPLIT_OFFSET_CAPTURE |
PREG_SPLIT_DELIM_CAPTURE |
PREG_SPLIT_NO_EMPTY
);
var_export($words);
?>
المخرجات :
قمت بتعديل المصفوفة لكي توضح الأبعاد الثنائية :
كود PHP:
array (
0 => array ( 0 => 'This', 1 => 0 ),
1 => array ( 0 => ' ', 1 => 4 ),
2 => array ( 0 => 'is', 1 => 5 ),
3 => array ( 0 => ' ', 1 => 7 ),
4 => array ( 0 => 'an', 1 => 8 ),
5 => array ( 0 => ' ', 1 => 10 ),
6 => array ( 0 => 'example', 1 => 11 ),
7 => array ( 0 => '.', 1 => 18 ),
)
* لي عودة مع الــmodifiers في مقال آخر بإذن الله "لا أعدكم ولكن يعيني الله كي أتفرغ لها وأعدها لكم".
أخيرا
هذا المقال نقطة فقط من بحر التعابير القياسية ، وأسأل الله لعل وعسى أن تكون هذه الجزئية سهلة الهضم و مستساغة ...