سؤال

أحتاج إلى regex يمكنها العثور على كتل من رمز PHP في ملف. فمثلا:

    <? print '<?xml version="1.0" encoding="UTF-8"?>';?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
    <head>
        <?php echo "stuff"; ?>
    </head>
    <html>

عندما يعود التحليل بواسطة Regex:

array(
    "<? print '<?xml version=\"1.0\" encoding="UTF-8"?>';?>",
    "<? echo \"stuff\"; ?>"
);

يمكنك افتراض أن PHP صالح.

هل كانت مفيدة؟

المحلول

مع token_get_all تحصل على قائمة من رموز لغة PHP من رمز PHP معين. ثم تحتاج فقط إلى تكرار القائمة ، ابحث عن الرموز المفتوحة وعلامات الإغلاق المقابلة.

$blocks = array();
$opened = false;
foreach (token_get_all($code) as $token) {
    if (!$opened) {
        if (is_array($token) && ($token[0] === T_OPEN_TAG || $token[0] === T_OPEN_TAG_WITH_ECHO)) {
            $opened = true;
            $buffer = $token[1];
        }
    } else {
        if (is_array($token)) {
            $buffer .= $token[1];
            if ($token[0] === T_CLOSE_TAG) {
                $opened = false;
                $blocks[] = $buffer;
            }
        } else {
            $buffer .= $token;
        }
    }
}

نصائح أخرى

هذا هو نوع المهمة التي هي أكثر ملاءمة للحجم المخصص. يمكنك بناء واحدة بسهولة نسبيا باستخدام مكدس ويمكنني أن أضمن أنك ستتم بشكل أسرع بكثير وسحب أقل شعرًا مما ستحاول تصحيح regex الخاص بك.

تعتبر التعبيرات العادية أدوات رائعة عند استخدامها بشكل مناسب ولكن ليس كل مهام تحليل النصوص متساوية.

جرب regex التالي باستخدام preg_match()

/<\?(?:php)?\s+(.*?)\?>/

هذا لم يختبر ، لكنه بداية. إنه يفترض علامة PHP الختامية (يمكن القول أنها تم تشكيلها جيدًا).

جرب هذا regex (لم يخبر):

preg_match_all('@<\?.*?\?>@si',$html,$m);
print_r($m[0]);
<\?(?:php)?\s+.*?\?>$

مع المعدلات التالية:

نقطة تطابق الخطوط الجديدة

^& Match at Line Breaks

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top