Regex для соответствия пространств имен в PHP - PullRequest
0 голосов
/ 17 июля 2009

сегодня моя цель - извлечь все имена классов PHP, связанные с
их имена пространства имен, но я застрял. Вот пример того, что у меня есть:

$content =<<<END
<?php

namespace test;

class a { }

class b { }

namespace foo;

class bar { }
?>
END;

preg_match_all('~^\s*((?:namespace)\s+(\w+);)?\s*(?:abstract\s+|final\s+)?(?:class|interface)\s+(\w+)~mi', $content, $classes);
var_dump($classes);

Выражение работает, только если в пространстве имен не более одного класса, но я не могу понять, как сделать так, чтобы оно соответствовало всем классам в соответствии с пространством имен.

Ответы [ 2 ]

5 голосов
/ 26 марта 2015

Вы можете попробовать следующий шаблон:

((?:\\{1,2}\w+|\w+\\{1,2})(?:\w+\\{0,2})+)

По какой-то причине мне пришлось сопоставить Namespace\Class и Namespace\\Class. Но вы должны заменить {1,2} и {0,2} соответственно ничем и ?

Проверьте это онлайн: https://regex101.com/r/fE2kU9/3

4 голосов
/ 17 июля 2009

Возможно, проще использовать токенайзер PHP * вместо регулярного выражения. Просто просмотрите список токенов в поисках T_NAMESPACE и T_CLASS.

Пример (не проверено):

$map = array();
$tokens = token_get_all($source_code);
$namespace = 'GLOBAL';
foreach ($tokens as $token) {
    if (!is_string($token)) {
        list($id, $text) = $token;
        if ($id == T_NAMESPACE) {
            $namespace = $text;
        }
        if ($id == T_CLASS) {
            $map[$namespace] = $text;
        }
    }
}
print_r($map);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...