首页 > 解决方案 > PHP:用于从代码源中捕获 DocBlocks 和相应函数定义的正则表达式

问题描述

我需要解析 PHP 源代码以捕获具有所属函数的现有 DocBlocks。遵循 DocBlock 的通用定义以及它们旁边的功能:

/**
 * Some line of DocBlock
 * ... DocBlock body, one or more lines started with ' * ' ...
 *
 */
[public] [static] function Some_Function (param1, param2, ...) {

请注意,可能有带有一些附加关键字的简单函数或类方法(private, public, ...)

上面的示例可以表示为带有项目的结构:

  1. Doc Block body from '/**'to '*/'(多行字符串)。
  2. 仅遵循一个换行符(\r\n\n取决于操作系统)。
  3. 从行首开始可能有一个或多个制表符 ( \t) 或空格 ( ) 字符 (NOT )。\h\s
  4. 可能的一个或多个关键字(private, public, ...),由 common 分隔[\s]+
  5. 必需的函数名,一个单词 ' Some_Function' 由 common 封闭[\s]+
  6. (param1, param2, ...)参数 ' ' 的必需括号

我需要抓住:

  1. Doc Block body from '/**'to '*/'from item (1) 作为结果集中的单独条目/子掩码。
  2. 完整的函数定义字符串,包括从 (4) 到 (6) 的项目,作为结果集中的单独条目/子掩码。
  3. 项目 (5) 中的函数名称作为结果集中的单独条目/子掩码。

目前我使用两个 preg_match_all 表达式来捕获它们,但只能以分开的方式(分两步):

// Catch all docblock definitions.
preg_match_all("!/\*\*.*?\*/!s", $data, $docblocks, PREG_OFFSET_CAPTURE);

// Catch all function definitions with one linebreak before
// (to identify the end position of previous docblock if exists one).
preg_match_all("/(?:\r\n|\n){1}[\t\h]*(\w+\s+)*function[\s]+(\S+)[\s]*\(.*\)/", $data, $functions, PREG_OFFSET_CAPTURE|PREG_UNMATCHED_AS_NULL);

这也是正确的,因为我还需要在没有 DocBlocks 的情况下捕获未链接的 DocBlocks 和函数。

接下来(需要时)我通过循环中的偏移位置(使用 PREG_OFFSET_CAPTURE)链接两个结果:

foreach ($docblocks[0] as &$docblock) {
  // Add new entry to store DockBlock ending offset position
  $docblock[2] = $docblock[1] + strlen($docblock[0]);
  // Lookup for linked function by offset value.
  $function_index = array_search($docblock[2], array_column($functions[0], 1));
  if ($function_index !== FALSE) {
    $docblock[3] = $functions[0][$function_index][1];
  }
}

但这很难处理。所以我仍然需要上面描述的第三种常见的组合表达式。我已经尝试了许多组合表达的变体,但总是得到“贪婪”的结果。

谢谢有人帮助我。

标签: phpregexparsingpreg-match-all

解决方案


推荐阅读