【问题标题】:Find PHP with REGEX使用正则表达式查找 PHP
【发布时间】:2010-07-02 14:44:37
【问题描述】:

我需要一个可以在文件中查找 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 是有效的。

【问题讨论】:

    标签: php regex parsing php-parser


    【解决方案1】:

    使用token_get_all,您可以获得给定PHP 代码的PHP language tokens 列表。然后您只需要迭代列表,查找打开标记标记和相应的关闭标记。

    $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;
            }
        }
    }
    

    【讨论】:

    【解决方案2】:

    这是更适合自定义解析器的任务类型。您可以使用堆栈相对轻松地构建一个,我可以保证您将比尝试调试正则表达式更快地完成并且减少头发。

    如果使用得当,正则表达式是很好的工具,但并非所有文本解析任务都是平等的。

    【讨论】:

    • 真正的解析器并不是必需的。标记器将完成这项工作。幸运的是,正如 Gumbo 指出的那样,PHP 内置了一个。 :)
    【解决方案3】:

    使用preg_match()尝试以下正则表达式

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

    这是未经测试的,但只是一个开始。它假定一个结束 PHP 标记(可以说是格式正确的)。

    【讨论】:

    • 我需要处理在其他 PHP 标记旁边有 's 作为字符串(如示例中)的情况。
    • PHP 不是 XML。从这个意义上说,它不可能是格式良好的
    • @Gordon:“[a] 格式良好的公式 [...] 是一个单词 [...],它是正式语言的一部分”en.wikipedia.org/wiki/Well-formed_formula
    • @Kendall,是的,这很难。您可能想使用上面的 Gumbo。另外,我不鼓励使用 PHP 短标签。
    • @back2dos 单词的含义取决于它们所使用的上下文。结束标记上下文中的格式良好指的是XML(或 SGML),而 PHP 不是。此外,当不在模板上下文中使用时,建议省略结束标记。这可以防止在结束标记之后包含空格的脚本输出任何空格,这会干扰发送标头。
    【解决方案4】:

    试试这个正则表达式(未经测试):

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

    【讨论】:

      【解决方案5】:
      <\?(?:php)?\s+.*?\?>$
      

      使用以下修饰符:

      点匹配换行符

      ^& 匹配换行符

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-12
        • 2012-04-25
        • 2012-12-01
        • 1970-01-01
        相关资源
        最近更新 更多