اذهب إلى المحتوى

التعابير النمطية (regexp/PCRE) في PHP


سارة محمد2
المعامل تفاصيل
‎$pattern ‎سلسلة نصية مع تعبير منطقي (نمط PCRE)

مطابقة تعبير نمطي عام

يمكن إجراء المطابقة باستخدام الدالة preg_match_all التي تعيد كل النتائج المطابقة في السلسلة النصية المُدخلة (على عكس الدالة preg_match التي تعيد النتيجة الأولى فقط).

تعيد الدالة preg_match_all عدد التطابقات، وسيحتوي المعامل الثالث ‎$matches على التطابقات بتنسيق تتحكم به الرايات التي يمكن وضعها في المعامل الرابع.

إذا كان لديك مصفوفة سيحتوي المعامل ‎$matches على مصفوفة بتنسيق مشابه لمصفوفتك مع الدالة preg_match، باستثناء أن preg_match تتوقف عند التطابق الأول، حيث تكرر preg_match_all عبر السلسلة النصية حتى تنتهي وتعرض نتيجة كل تكرار في مصفوفة متعددة الأبعاد والتي يمكن التحكم بتنسيقها باستخدام الراية في المعامل الرابع.

يتحكم المعامل الرابع ‎$flags في بنية مصفوفة ‎$matches، النمط الافتراضي هو PREG_PATTERN_ORDER والرايات الممكنة PREG_SET_ORDER وPREG_PATTERN_ORDER.

توضح الشيفرة التالية استخدام preg_match_all:

$subject = "a1b c2d3e f4g";
$pattern = '/[a-z]([0-9])[a-z]/';

var_dump(preg_match_all($pattern, $subject, $matches, PREG_SET_ORDER)); // int(3)
var_dump($matches);
preg_match_all($pattern, $subject, $matches);
var_dump($matches);

// preg_match نفس التعبير المنطقي يُنفَّذ بالدالة
preg_match($pattern, $subject, $matches);
var_dump($matches);

خرج الشيفرة var_dump($matches);‎ الأولى:

array(3) {
    [0]=>
    array(2) {
        [0]=>
        string(3) "a1b"
        [1]=>
        string(1) "1"
    }
    [1]=>
    array(2) {
        [0]=>
        string(3) "c2d"
        [1]=>
        string(1) "2"
    }
    [2]=>
    array(2) {
        [0]=>
        string(3) "f4g"
        [1]=>
        string(1) "4"
    }
}

لدى ‎$matches ثلاث مصفوفات متداخلة تمثل كل منها تطابقًا لها نفس تنسيق القيمة المعادة من preg_match.

خرج الشيفرة var_dump($matches);‎ الثانية حيث الراية هي الراية الافتراضية PREG_PATTERN_ORDER:

array(2) {
    [0]=>
    array(3) {
        [0]=>
        string(3) "a1b"
        [1]=>
        string(3) "c2d"
        [2]=>
        string(3) "f4g"
    }
    [1]=>
    array(3) {
        [0]=>
        string(1) "1"
        [1]=>
        string(1) "2"
        [2]=>
        string(1) "4"
    }
}

عندما يُنفّذ نفس التعبير المنطقي باستخدام preg_match تكون المصفوفة المُعادة:

array(2) {
    [0] =>
    string(3) "a1b"
    [1] =>
    string(1) "1"
}

تطابق سلسلة نصية مع تعبير نمطي

تتحقق الدالة preg_match من تطابق سلسلة نصية مع تعبير نمطي.

$string = 'This is a string which contains numbers: 12345';

$isMatched = preg_match('%^[a-zA-Z]+: [0-9]+$%', $string);
var_dump($isMatched); // bool(true)

إذا مررت معاملًا ثالثًا سيُملأ بالبيانات المُطابقة من التعبير النمطي:

preg_match('%^([a-zA-Z]+): ([0-9]+)$%', 'This is a string which contains numbers: 12345',
$matches);

// الآن على نتائج مطابقة التعبير النمطي في مصفوفة $matches تحتوي 
echo json_encode($matches); // ["numbers: 12345", "numbers", "12345"]

تحتوي ‎$matches على مصفوفة لكل المطابقات ثم السلاسل النصية الجزئية في التعبير النمطي محاطة بقوسين، بترتيب إزاحة الأقواس المفتوحة. أي إذا كان لديك التعبير المنطقي ‎/z(a(b))/‎ سيحتوي الفهرس 0 على كامل السلسلة النصية zab ويحتوي الفهرس 1 على السلسلة النصية الجزئية مُحاطة بالأقواس الخارجية ab ويحتوي الفهرس 2 على السلسلة النصية الجزئية المحاطة بالأقواس الداخلية b.

تقسيم سلسلة نصية إلى مصفوفة باستخدام تعبير نمطي

إليك معاني أجزاء التعبير المنطقي ‎/[0-9]+\|/‎ في الشيفرة أدناه:

  • [0-9]: أي محرف مفرد في المجال من 0 إلى 9.
  • +: واحد أو أكثر من 0 إلى 9.

ومعاني أجزاء التعبير المنطقي ‎/[\d]+\|/‎:

  • []: صنف المحارف
  • ‎\d‎: أي رقم
  • +: رقم أو أكثر
$string = "0| PHP 1| CSS 2| HTML 3| AJAX 4| JSON";

$array = preg_split("/[0-9]+\|/", $string, -1, PREG_SPLIT_NO_EMPTY);
// أو
$array = preg_split("/[\d]+\|/", $string, -1, PREG_SPLIT_NO_EMPTY);

الخرج:

Array
(
    [0] => PHP
    [1] => CSS
    [2] => HTML
    [3] => AJAX
    [4] => JSON
)

يمكنك ببساطة تقسيم سلسلة نصية إلى مصفوفة بتمرير السلسلة النصية والتعبير النمطي للدالة preg_split()‎، وللمطابقة والبحث نضيف المعامل الثالث (limit) الذي يسمح لنا بضبط عدد التطابقات التي نريدها وتُضاف السلسلة النصية الباقية إلى نهاية المصفوفة.

ضبطنا المعامل الرابع (flags) في مثالنا إلى القيمة PREG_SPLIT_NO_EMPTY التي تمنع المصفوفة من الاحتواء على أي قيم / مفاتيح فارغة.

استبدال السلسلة النصية مع التعبير النمطي

يمثل ‎$1 و‎$2 و‎‎$3 في الشيفرة التالية المجموعات الملتقطة الأولى والثانية والثالثة.

$string = "a;b;c\nd;e;f";
echo preg_replace("(^([^;]+);([^;]+);([^;]+)$)m", "$3;$2;$1", $string);

الخرج:

c;b;a
f;e;d

تبحث عن كل ما هو بين الفواصل المنقوطة وتعكس الترتيب.

استبدال سلسلة نصية مع رد النداء

تعمل الدالة preg_replace_callback بإرسال كل مجموعة ملتقطة مطابقة إلى رد النداء المعرَّف وتستبدلها مع القيمة المعادة من رد النداء، وهذا يسمح لنا باستبدال سلسلة نصية اعتمادًا على أي نوع من المنطق.

$subject = "He said 123abc, I said 456efg, then she said 789hij";
$regex = "/\b(\d+)\w+/";

// تستبدل هذه الدالة المداخل المطابقة شرطيًا بالاعتماد على المحرف الأول للمجموعة الملتقطة
function regex_replace($matches){
    switch($matches[1][0]){
        case '7':
            $replacement = "<b>{$matches[0]}</b>";
            break;
        default:
            $replacement = "<i>{$matches[0]}</i>";
        }
        return $replacement;
}

$replaced_str = preg_replace_callback($regex, "regex_replace", $subject);

print_r($replaced_str);

// He said <i>123abc</i>, I said <i>456efg</i>, then she said <b>789hij</b>

ترجمة -وبتصرف- للفصل [Regular Expressions (regexp/PCRE)‎] من كتاب PHP Notes for Professionals book

اقرأ أيضًا


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...