中文参数文本里的数值与单位归一化:抽取成可比字段

发布时间:2026/10/20 9:09:16
中文参数文本里的数值与单位归一化:抽取成可比字段 技术资料里最常见的一个困境是同一项参数在不同页面写成不同样子。厚度 3mm厚度 3 毫米板厚≤3.0mm加工精度 0.05—0.1 毫米人一眼就知道在说同一件事程序却比不出来。想做参数一致性校验、范围校验或者结构化入库第一步绕不开归一化。下面这套实现处理四类现实问题中文与英文单位混写、全角数字与千分位、比较符号不大于、不小于、约、区间、以及一段文本里连写多个数量。目标不是做一个通用解析器而是把抽取结果落成能直接比较的字段量纲、基准值、下限、上限、符号、原文。单位表与基准量纲先把单位映射到同一量纲下的基准单位。这里刻意把量纲显式列出因为跨量纲比较是这类代码最容易出的错——把3 升与3 千克当成同一项参数比对结果看起来正常实际全是错的。DIMENSIONS { 长度: {mm: 1.0, 毫米: 1.0, cm: 10.0, 厘米: 10.0, m: 1000.0, 米: 1000.0, km: 1000000.0, 公里: 1000000.0}, 质量: {g: 1.0, 克: 1.0, kg: 1000.0, 千克: 1000.0, 公斤: 1000.0, t: 1000000.0, 吨: 1000000.0}, 温度: {℃: 1.0, °C: 1.0, 摄氏度: 1.0}, 体积: {ml: 1.0, 毫升: 1.0, l: 1000.0, L: 1000.0, 升: 1000.0}, 比例: {%: 1.0, percent: 1.0}, } UNIT_INDEX {} for dim, table in DIMENSIONS.items(): for unit in table: UNIT_INDEX.setdefault(unit.lower(), (dim, table[unit]))映射表用小写键索引查询时把候选单位也转小写可以省掉 L/l、Mm/MM 这一类大小写分裂。温度不参与倍率换算基准系数一律写 1.0避免后续误把量纲当可乘单位。数字与符号的解析中文技术文本里的数字形态比想象中多全角、半角混用千分位带逗号负号有短横与连字符两种。解析函数把这些折叠成浮点数同时单独返回比较符号。import re FULL_TO_HALF str.maketrans(, 0123456789.-) NUM_PATTERN r[-]?\d[\d,]*(?:\.\d)? OP_ALIASES {≤: , ≦: , : , ≥: , : , 不大于: , 不小于: , 约: ~, ≈: ~, 以内: , 以上: } def parse_number(raw): text raw.translate(FULL_TO_HALF).replace(,, ) return float(text)OP_ALIASES这张表需要按行业语料维护。以内和以下在很多语境里等价但以下在温度语境里含义更模糊建议先只登记本企业语料里出现过的写法遇到未知写法保留符号原文不要靠猜。抽取一条正则覆盖四种形态抽取的目标形态有四种单值、带符号的单值、闭区间、以及一个短语里的多值。用一条带可选组的正则即可覆盖剩下的交给后处理。TOKEN r(?:%s) % NUM_PATTERN RANGE_SEP r(?:[-—~]|至|到) PATTERN re.compile( r(?Pop[≤≦≥≈]{0,2}|不大于|不小于|约|以内|以上)? r\s*(?Pn1%s)\s*(?Pu1[a-zA-Z]{1,3}|[\u4e00-\u9fa5]{1,3}|%%)? r(?:\s*%s\s*(?Pn2%s)\s*(?Pu2[a-zA-Z]{1,3}|[\u4e00-\u9fa5]{1,3}|%%)?)? % (TOKEN, RANGE_SEP, TOKEN) )单位组写成拉丁字母1 到 3 位、汉字1 到 3 位或百分号几个限定都是必要的。上限 3 是防止正则把紧随其后的量词或连接字吞进单位里得到毫米厚这种查不到映射的键百分号写成%%不是笔误因为这条正则是用 %-格式化拼出来的模式里的字面量%必须双写单写会在编译期抛ValueError: unsupported format character下限 1 更隐蔽——如果把单位组写成可以匹配零个字符正则会在数字后先接受一个空单位拉丁单位mm、kg整段被漏掉而中文单位因为能匹配汉字看起来一切正常。查不到映射时按未知单位返回不要静默返回默认量纲。后处理把匹配结果变成可比字段拿到匹配片段之后分三步收尾判定量纲、换算到基准单位、按符号决定值落在下限还是上限。区间与单值走同一套出口比对逻辑就不需要分支。def to_field(match): op (match.group(op) or ).strip() op OP_ALIASES.get(op, op) v1 parse_number(match.group(n1)) unit (match.group(u1) or match.group(u2) or ).strip() info UNIT_INDEX.get(unit.lower()) if not info: return {raw: match.group(0), dimension: None, value: v1, unit: unit, op: op, note: unit-unknown} dim, factor info low, high v1 * factor, v1 * factor if match.group(n2): high parse_number(match.group(n2)) * factor return {raw: match.group(0), dimension: dim, low: low, high: high, op: op, unit: unit}百分比和温度这两类要单独打标记。百分比的基准值直接用原数即可但3和3%在文本里外观接近抽取时如果没有取到%建议返回unit-unknown而不是默认按单值处理。三条实测出来的经验· 多值连写要单独处理。长 3 米、宽 1.2 米用一条正则整体匹配会把长当成单位的一部分。做法是按分隔符顿号、逗号、分号先切短语再对每个短语单独抽值。· 抽取结果保留原文。字段里带raw出现争议时能立刻定位是哪一句文本被解析错了只存数值的话排错成本会成倍上升。· 单位表按版本落盘。这张表一旦改动历史抽取结果就不可比。把它连同版本号一起写成配置比写在代码里更容易复核。按这套实现在一批约 400 页的工业品参数文本上跑抽取召回接近全量误报集中在未知单位那一类逐条补进映射表即可收敛。本文由一支长期做工业文本结构化与数据质量检测的技术团队整理欢迎同行交流指正。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询