You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CodeIgniter模块化应用中如何用正则提取HMVC模块变量?

解决CodeIgniter HMVC标签的正则匹配问题

我来帮你搞定这个正则匹配的问题~你之前写的正则要么只能匹配固定的{module}标签,要么没法正确解析属性键值对,肯定满足不了需求。咱们来一步步调整,写出能准确匹配{modulename limit="x" start="y" template="z"}这种格式的正则。

首先分析需求

我们需要匹配的标签结构是:

  • 以{开头,}结尾
  • 开头是自定义模块名(比如news、products,一般是字母/数字/下划线)
  • 后面跟着0个或多个属性键值对,格式是key="value",属性之间用空格分隔

可行的正则方案

第一步:匹配完整标签,分离模块名和属性字符串

先写一个正则把整个标签拆成模块名和属性部分:

$tagRegex = '/\{(\w+)\s*(.*?)\}/';

解释下每个部分:

  • \{:转义左大括号,因为它是正则的特殊字符
  • (\w+):捕获模块名,\w匹配字母、数字、下划线,+表示至少一个字符
  • \s*:匹配模块名和属性之间的0个或多个空白(空格、换行、制表符都算)
  • (.*?):非贪婪匹配属性字符串,直到遇到右大括号}为止
  • \}:转义右大括号

第二步:解析属性字符串为键值对数组

拿到属性字符串后,再用另一个正则提取每个key="value":

$attrRegex = '/(\w+)="([^"]*)"/';

解释:

  • (\w+):捕获属性名
  • =":匹配属性名和值之间的="
  • ([^"]*):捕获属性值,[^"]表示非双引号字符,*表示0个或多个(支持空值)

完整PHP代码示例

结合起来,你可以这样处理页面内容里的HMVC标签:

// 示例页面内容
$pageContent = '首页展示{news limit="5" start="0" template="list_card"},热门商品{products limit="3" template="grid"}';

// 第一步:匹配所有模块标签
preg_match_all('/\{(\w+)\s*(.*?)\}/', $pageContent, $tagMatches, PREG_SET_ORDER);

foreach ($tagMatches as $tagMatch) {
    // 提取模块名
    $moduleName = $tagMatch[1];
    // 提取属性字符串
    $attrString = $tagMatch[2];
    
    // 第二步:解析属性为数组
    $attributes = [];
    preg_match_all('/(\w+)="([^"]*)"/', $attrString, $attrMatches, PREG_SET_ORDER);
    foreach ($attrMatches as $attr) {
        $attributes[$attr[1]] = $attr[2];
    }
    
    // 这里就可以调用你的HMVC逻辑了
    // 比如:加载模块、传入属性、渲染模板
    // $moduleOutput = $this->load->module($moduleName, $attributes);
    
    // 打印测试结果
    echo "模块名:{$moduleName}\n";
    echo "属性:";
    print_r($attributes);
    echo "\n---\n";
}

为什么你之前的正则不行?

  • 第一个正则preg_match_all('/{module}/', $page, $match):只能匹配固定的{module}标签,既不支持自定义模块名,也没法处理属性。
  • 第二个正则preg_match_all('/{module(\S+)}/', $page, $match):不仅模块名固定为module,而且\S+会把所有非空白字符(包括属性的limit="5")都当成一堆乱码,根本没法拆分出单独的属性键值对。

额外优化(可选)

如果你的标签属性允许用单引号(比如limit='5'),可以把属性正则改成支持双引号和单引号:

$attrRegex = '/(\w+)=(["\'])(.*?)\2/';

这个正则会自动识别属性值用的是双引号还是单引号,并且正确捕获值(包括转义的同类型引号,比如value="it\'s ok")。

内容的提问来源于stack exchange,提问作者Dyam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:43:48