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

如何从模板字符串提取数据?求更优雅的PHP实现方案

问题:通过模板从字符串中提取结构化数据

需求示例:

// 现有内容
$utterance = 'This is a brown bear with 7 kids';
$template = 'This is a {color} bear with {kids} kids';

// 期望输出
[
  "color" => "brown",
  "kids" => "7",
]

当前使用的粗糙实现方案:

$regex = '/' . preg_replace('/{.*?}/' , '.*?', $template) . '/i';

foreach(preg_split('/\{.*?\}/', $template) as $part) {      
  $utterance = str_replace($part, Str::startsWith($template, $part) || Str::endsWith($template, $part)  ? '' : '|', $utterance);
}

preg_match_all('/{(.*?)}/', $template, $variables);

$values = explode('|', $utterance);
$variables = $variables[1];

array_combine($variables, $values);

希望得到更简洁的实现方式。


更简洁的实现方案

可以直接将模板转换为带捕获组的正则表达式,通过一次正则匹配就能提取对应变量的值,无需额外的字符串替换与拆分操作,代码逻辑更清晰高效:

// 提取模板中的变量名
preg_match_all('/\{(.*?)\}/', $template, $varMatches);
$variableNames = $varMatches[1];

// 将模板转换为正则匹配模式:转义特殊字符,把{变量}替换为捕获组
$regexPattern = preg_replace('/\{.*?\}/', '(.*?)', preg_quote($template, '/'));
$regexPattern = "/^$regexPattern$/i"; // 添加上下文边界确保完全匹配

// 执行匹配并提取结果
preg_match($regexPattern, $utterance, $valueMatches);
array_shift($valueMatches); // 移除正则返回的完整匹配项

// 组合成目标键值对数组
$result = array_combine($variableNames, $valueMatches);

关键细节说明:

  • preg_quote($template, '/'):转义模板中的正则特殊字符(比如., *等),避免破坏正则语法;
  • 捕获组规则:示例中用(.*?)非贪婪匹配任意字符,若变量值仅为非空白字符,可改为([^\s]+?)提升匹配精度;
  • 边界约束:^和$确保整个字符串与模板完全匹配,避免部分匹配导致的错误结果。

如果需要支持变量值包含空格的场景,上述代码直接可用;若变量值仅为数字或特定格式,可进一步调整捕获组的正则规则(比如数字用(\d+))。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 20:15:34