如何用pyparsing在语法中表示可选组件?药物剂量解析问题
解决药物剂量表达式解析问题
问题核心在于两点:
- 介词与药物名称规则重叠:你定义的
preposition是任意字母组成的单词,和chemical的匹配规则高度重叠,导致无介词时解析器会把药物名称误判为介词,进而因找不到后续chemical报错。 - 未限定介词范围:没有明确哪些单词是介词,而是匹配所有字母单词,这是规则冲突的根源。
下面是修正后的实现代码:
import pyparsing as pp # 定义数字和单位,支持连写(如10mg)或空格分隔(如10 mg) dose_num = pp.Word(pp.nums) unit = pp.Word(pp.alphas) # 合并数字与单位为剂量部分,同时保留拆分结果 dose = dose_num + unit # 限定介词为常见的特定词汇,避免与药物名称混淆 prepositions = pp.oneOf(["of", "for", "with"]) # 药物名称限定为字母组成(可根据需求扩展,比如支持连字符、空格等) drug_name = pp.Word(pp.alphas) # 构建解析器:剂量 + 可选介词 + 药物名称 dosage_parser = dose + pp.Optional(prepositions) + drug_name # 测试不同输入 print(dosage_parser.parseString('10mg of aspirin')) # ['10', 'mg', 'of', 'aspirin'] print(dosage_parser.parseString('10 mg aspirin')) # ['10', 'mg', 'aspirin'] print(dosage_parser.parseString('10mg aspirin')) # ['10', 'mg', 'aspirin']
如果需要直接提取合并后的完整剂量(如"10mg")和药物名称,可以给解析器分组并设置结果名称:
import pyparsing as pp dose_num = pp.Word(pp.nums) unit = pp.Word(pp.alphas) # 合并数字与单位为完整剂量字符串,支持数字和单位间有空格 dose = pp.Combine(dose_num + pp.Optional(pp.White()) + unit).setResultsName("dose") prepositions = pp.oneOf(["of", "for", "with"]) drug_name = pp.Word(pp.alphas).setResultsName("drug") dosage_parser = dose + pp.Optional(prepositions) + drug_name # 提取结构化结果 result1 = dosage_parser.parseString('10mg of aspirin') print(f"剂量: {result1.dose}, 药物名称: {result1.drug}") # 剂量: 10mg, 药物名称: aspirin result2 = dosage_parser.parseString('10 mg aspirin') print(f"剂量: {result2.dose}, 药物名称: {result2.drug}") # 剂量: 10mg, 药物名称: aspirin
关键修改说明
- 限定介词范围:用
pp.oneOf指定具体介词列表,彻底解决规则冲突问题,让解析器能明确区分介词和药物名称。 - 优化剂量匹配:通过
pp.Combine合并数字与单位,同时保留对空格分隔场景的支持,方便后续直接使用完整剂量值。 - 结构化结果提取:使用
setResultsName给解析结果命名,无需手动处理列表下标,更直观地获取剂量和药物名称。
内容的提问来源于stack exchange,提问作者mac389
相关产品推荐
相关产品推荐

