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

文本转十进制数值:解决‘three and half’场景的转换问题

解决英文数量词带分数的识别问题

现有Python代码可将文本中的英文数量词(如“three”)转换为十进制数值,但无法处理“three and half”这类带分数的表述,导致番茄的数量被错误识别为0.5,需要优化代码以正确转换为3.5。

输入示例

"Please get me a three and half of tomato and one bottle of milk, 3 kilos of carrots and half kilo of beans finally 1 bottle water, thank you"

当前错误输出

Shopping list:
1 bottle milk
3.0 kilo carrots
0.5 kilo tomato
1.0 bottle water
0.5 kilo beans

期望输出

Shopping list:
1 bottle milk
3.0 kilo carrots
3.5 kilo tomato
1.0 bottle water
0.5 kilo beans

解决方案

核心需修改两个部分:正则表达式以匹配带分数的数量结构,以及数量转换函数以处理组合式的数量计算。

修改步骤

  • 更新正则表达式:新增匹配数字/数量词 + and + half/quarter的结构,确保捕获完整的带分数表述
  • 扩展数量转换函数:处理捕获到的组合数量,将整数部分和分数部分相加得到正确数值
  • 调整匹配结果处理逻辑:针对单独数量、组合数量两种匹配结果进行对应转换

修改后的完整代码

import re
from collections import OrderedDict

products = {
    "milk": ["milk"],
    "carrots": ["carrot", "carrots"],
    "tomato": ["tomato", "tomatoes"],
    "water": ["water"],
    "beans": ["beans"]
    # 可添加更多产品
}

def convert_to_decimal(quantity_parts):
    # 处理组合数量(如("three", "half"))
    if isinstance(quantity_parts, tuple):
        integer_part = quantity_parts[0].lower()
        fraction_part = quantity_parts[1].lower()
        words_to_numbers = {
            'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5,
            'six': 6, 'seven': 7, 'eight': 8, 'nine': 9, 'ten': 10
        }
        integer_val = words_to_numbers.get(integer_part, 0.0) if not integer_part.isdigit() else float(integer_part)
        fraction_val = {'half': 0.5, 'quarter': 0.25}[fraction_part]
        return integer_val + fraction_val
    # 处理单独数量
    quantity_text = quantity_parts.lower()
    if quantity_text in ['half', 'quarter']:
        return {'half': 0.5, 'quarter': 0.25}[quantity_text]
    elif quantity_text.isdigit():
        return float(quantity_text)
    else:
        words_to_numbers = {
            'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5,
            'six': 6, 'seven': 7, 'eight': 8, 'nine': 9, 'ten': 10
        }
        return words_to_numbers.get(quantity_text, 0.0)

def create_shopping_list(text):
    items = OrderedDict()
    for product, keywords in products.items():
        for keyword in keywords:
            # 正则表达式:匹配两种情况:1. 单独数量词/数字;2. 数量词/数字 + and + half/quarter
            pattern = fr'((\d+(?:\.\d+)?|\b(?:one|two|three|four|five|six|seven|eight|nine|ten)\b)\s+and\s+(half|quarter)|\b(?:half|quarter|one|two|three|four|five|six|seven|eight|nine|ten)\b|\d+(?:\.\d+)?)' \
                      fr'\s*(?:bottle|kilo)?s?\s*(?:of\s*)?{keyword}'
            matches = re.findall(pattern, text, re.IGNORECASE)
            for match in matches:
                # 提取有效匹配:如果是组合结构,取第2、3组;否则取第0组
                if match[1] and match[2]:
                    quantity = convert_to_decimal((match[1], match[2]))
                else:
                    quantity = convert_to_decimal(match[0])
                items.setdefault(product, set()).add(quantity)

    result = []
    for product, quantities in items.items():
        for quantity in quantities:
            # 根据产品类型设置单位
            unit = 'bottle' if product in ['milk', 'water'] else 'kilo'
            result.append(f"{quantity} {unit} {product}")

    # 去重并保留顺序
    unique_shopping_list = list(dict.fromkeys(result))
    return unique_shopping_list

# 示例使用
user_input = "Please get me three and half kilo of tomato and one bottle of milk, 3 kilos of carrots and half kilo of beans finally 1 bottle water, thank you"
shopping_list = create_shopping_list(user_input)
if shopping_list:
    print("Shopping list:")
    for item in shopping_list:
        print(item)
else:
    print("No items found in the input.")

关键修改说明

  • 正则表达式:新增(\d+(?:\.\d+)?|\b(?:one|...|ten)\b)\s+and\s+(half|quarter)分支,捕获带and的分数组合,同时保留原有单独数量的匹配逻辑
  • convert_to_decimal函数:新增元组类型参数处理逻辑,当传入整数部分和分数部分的元组时,分别转换后相加得到最终数值
  • 匹配结果处理:遍历匹配结果时,判断是否为组合结构,将对应部分传入转换函数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 10:17:32