如何使用正则表达式在 PHP 中精准提取营养成分数据的类别、数值与单位

7次阅读

如何使用正则表达式在 PHP 中精准提取营养成分数据的类别、数值与单位

本文介绍如何通过 `preg_match_all` 配合命名捕获组正则,从多行营养标签文本中准确分离出成分名称(如 “total lipid (fat)”)、浮点数值(如 22.163422468932)和单位(如 “g”),避免错误切分标点与空格。

直接使用 preg_split 按数字或空格分割容易破坏语义完整性——例如将 “Total lipid (fat)” 错误拆成 [“Total”, “lipid”, “(fat)”],且难以保留数值与单位的边界。更可靠的做法是匹配(match)而非分割(split):用正则主动识别每行中“非数字开头的类别名 + 空格 + 浮点数 + 空格 + 单位”的结构,并通过命名捕获组提取三部分。

推荐正则模式如下:

$pattern = '~^(?PD+)s+(?P[d.]+)s+(?P.+)~m';
  • ^ 和 m 修饰符:使 ^ 匹配每一行开头(多行模式);
  • (?Pgory>D+):捕获一个或多个非数字字符(D),完美兼容含空格、逗号、括号的成分名(如 “Sugars, total” 或 “Sodium, Na”);
  • s+:匹配一个或多个空白符(含空格、制表符),作为分隔;
  • (?P[d.]+):捕获由数字和小数点组成的数值(注意:未限定小数点个数,适用于科学记数法外的常规浮点格式;若需更严格校验,可改为 (?Pd+(?:.d+)?));
  • (?P.+):捕获剩余所有字符作为单位(如 “kcal”、”mg”),自动包含末尾换行前的内容。

完整 php 示例代码:

$pattern = '~^(?PD+)s+(?P[d.]+)s+(?P.+)~m'; preg_match_all($pattern, $content, $matches, PREG_SET_ORDER);  // 输出结构化结果 foreach ($matches as $match) {     echo sprintf(         "[%s] => %sn[%s] => %sn[%s] => %snn",         'category', trim($match['category']),         'value',    $match['value'],         'unit',     trim($match['unit'])     ); } ?>

输出效果示例(首行):

立即学习PHP免费学习笔记(深入)”;

[category] => Weight   [value] => 229.6104534866   [unit] => g

⚠️ 注意事项:

  • 若输入中存在无单位行(如纯数值)或格式不一致(如缺失空格),该正则会跳过不匹配行——建议先用 trim() 清理每行首尾空白,并对 $matches[0] 进行空值检查;
  • 如需支持国际单位中的逗号千位分隔符(如 “1,234.56”),应将 [d.]+ 替换为更健壮的 [d,]+(?:.d+)? 并预处理去除逗号;
  • preg_match_all 返回的 $matches 是二维数组,PREG_SET_ORDER 保证每个子数组对应一行完整匹配,键名为 category/value/unit,便于后续 jsON 序列化或数据库插入。

这种方法语义清晰、容错性强,是解析结构化标签文本的标准实践。

text=ZqhQzanResources