preg_match负面看后面

时间:2014-01-29 01:22:03

标签: php regex preg-match phpdoc negative-lookbehind

我正在尝试用preg_match解析PHPDoc标签,但我遇到了一些负面的lookbehind问题。我之前从未使用过这些,但我的理解是它们被用作排除。

这是我的模式:

/\*\*.+?(?<! \*/)@access public.+? \*/\s+?function\s+[a-zA-Z0-9_]+\(

以下是我正在尝试解析的示例PHP文件:

<?php

/**
 * This is the shortcut to DIRECTORY_SEPARATOR
 */
defined('DS') or define('DS',DIRECTORY_SEPARATOR);

/**
 * Foo
 * 
 * @return bool
 * @access public
 */
function foo()
{
    return true;
}

我希望将任何函数与@access公共标记匹配,但在这种情况下,匹配从DS常量的注释开始。我认为(?<! \*/)会将其排除在与DS评论的结束评论标记匹配的位置。

我错过了什么?

3 个答案:

答案 0 :(得分:2)

在@bishop的link之后,我发现了一个使用负向前瞻的例子,对我有用。

我改变了

.+?(?<! \*/)

(?:(?! \*/).)+?

现在完整的模式是:

/\*\*(?:(?! \*/).)+?@access public.+? \*/\s+?function\s+[a-zA-Z0-9_]+\(

编辑:

也匹配函数类型和参数的完整模式:

(?<full>[\t ]*?/\*\*(?:(?! \*/).)+?@access public(?:(?! \*/).)+? \*/\s+?(?:public |protected |private )??(?:static )??function\s+[a-zA-Z0-9_]+\(.*?\))

和班级匹配:

(?<full>(?<indent>[\t ]*?)/\*\*(?:(?! \*/).)+?@access public.+? \*/\s+?(?:abstract )??class\s+[a-zA-Z0-9_]+\s??.*?{)

答案 1 :(得分:0)

负面的后视必须是固定长度的。听起来使用某种DocBlock解析器会更好。有许多解决方案。

答案 2 :(得分:0)

使用token_get_all()功能:

$tokens = token_get_all($code);
$result = array();

foreach ($tokens as $k=>$token) {
    switch ($token[0]):
        case T_DOC_COMMENT:
            $isPublic = strpos($token[1], '@access public');
            break;

        case T_FUNCTION:
            $isFunction = true;
            break;

        case T_WHITESPACE:
            break;

        case T_STRING:
            if ($isFunction && $isPublic) $result[] = $token[1];

        default:
            $isFunction = false;
    endswitch;
}    

print_r($result);

为了了解您可以使用tokenizer提取的内容,我建议您将以下代码放在foreach循环中,endswitch;下:

if ($isPublic && isset($token[1]))
    printf("%s\t%s\t%s\n", $token[0],
                           token_name($token[0]),
                           strtr($token[1], "\n", ' ')
                           );