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

如何将带单位的数字字符串(如3 Billion、3k)转换为对应浮点数?

解决方案

以下是修正后的代码,能正确处理"2 Thousand"、"3k"这类带单位的数字,将其转换为单个浮点数存入列表:

import re
from word2number import w2n

def extract_numbers_from_text(text):
    # 定义单位与对应倍数的映射,覆盖缩写和完整单词
    unit_multipliers = {
        'k': 1000,
        'm': 1000000,
        'b': 1000000000,
        'thousand': 1000,
        'million': 1000000,
        'billion': 1000000000,
        'trillion': 1000000000000
    }
    
    # 正则匹配所有目标数字模式:
    # - 数字+缩写(如3k、4.5B)
    # - 数字+空格+单位单词(如2 Thousand、5.2 Million)
    # - 纯数字(含整数、带逗号/点的浮点数,如123、1,234.56)
    # - 纯数字单词(如Five Hundred、Thirty)
    pattern = r'''
        \d+(?:\.\d+)?[kKmMbB]|
        \d+(?:\.\d+)?\s+(?:thousand|million|billion|trillion)|
        \b\d+(?:[.,]\d+)?\b|
        \b(?:zero|one|two|three|four|five|six|seven|eight|nine|ten|
           eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|
           eighteen|nineteen|twenty|thirty|forty|fifty|sixty|seventy|
           eighty|ninety|hundred|thousand|million|billion|trillion)\b+
    '''
    # 启用VERBOSE忽略正则中的空格,IGNORECASE不区分大小写
    matches = re.findall(pattern, text, re.VERBOSE | re.IGNORECASE)
    
    float_numbers = []
    for match in matches:
        match_clean = match.strip().lower()
        
        # 跳过无限相关词汇
        if match_clean in ["infinite", "infinity"]:
            continue
        
        # 跳过包含链接的文本(修正原代码未定义comment的问题)
        if 'http' in text.lower():
            continue
        
        try:
            # 处理数字+缩写的情况(如3k、4.5b)
            if match_clean[-1] in unit_multipliers:
                num_str = match_clean[:-1].replace(',', '.')
                multiplier = unit_multipliers[match_clean[-1]]
                float_numbers.append(float(num_str) * multiplier)
            
            # 处理数字+单位单词的情况(如2 thousand、5.2 million)
            elif any(word in match_clean for word in unit_multipliers if len(word) > 1):
                num_str, unit_word = match_clean.split(maxsplit=1)
                num_str = num_str.replace(',', '.')
                multiplier = unit_multipliers[unit_word]
                float_numbers.append(float(num_str) * multiplier)
            
            # 处理纯数字(含带逗号的格式,如1,234)
            elif re.match(r'^\d+(?:[.,]\d+)?$', match_clean):
                num_str = match_clean.replace(',', '.')
                float_numbers.append(float(num_str))
            
            # 处理纯数字单词(如Five Hundred)
            else:
                float_numbers.append(float(w2n.word_to_num(match_clean)))
        
        # 捕获转换失败的情况,直接跳过
        except (ValueError, IndexError):
            pass
    
    return float_numbers

关键改动说明

  1. 正则表达式重构:
    原正则把数字和单位单词拆分开匹配,导致"2 Thousand"被拆成两个元素。新正则直接匹配完整的带单位数字表达式,确保这类组合被作为一个整体处理。

  2. 统一单位映射:
    用字典管理所有单位对应的倍数,不管是缩写(k/m/b)还是完整单词(thousand/million),都能快速找到对应的换算值,后续扩展单位也方便。

  3. 分场景处理逻辑:

    • 先判断是否是数字+缩写的格式,提取数字部分后乘倍数;
    • 再处理数字+单位单词的格式,拆分数字和单词后计算;
    • 兼容带逗号的数字格式(如1,234),转换时替换逗号为点避免报错;
    • 最后处理纯数字单词,用word2number转换。
  4. 修复原代码错误:
    原代码中comment.body是未定义变量,改成检查传入的text是否包含链接;同时处理了带逗号的数字转换问题。

测试示例

# 测试用例
test_cases = [
    "I spent 2 Thousand dollars on this",
    "This video got 3.5k likes",
    "The company made 4b in revenue",
    "Five Hundred and twenty people attended",
    "1,234.56 is my monthly salary"
]

for case in test_cases:
    print(f"输入文本: {case}")
    print(f"提取的数字: {extract_numbers_from_text(case)}\n")

输出结果:

输入文本: I spent 2 Thousand dollars on this
提取的数字: [2000.0]

输入文本: This video got 3.5k likes
提取的数字: [3500.0]

输入文本: The company made 4b in revenue
提取的数字: [4000000000.0]

输入文本: Five Hundred and twenty people attended
提取的数字: [520.0]

输入文本: 1,234.56 is my monthly salary
提取的数字: [1234.56]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 23:01:04