如何将带单位的数字字符串(如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
关键改动说明
正则表达式重构:
原正则把数字和单位单词拆分开匹配,导致"2 Thousand"被拆成两个元素。新正则直接匹配完整的带单位数字表达式,确保这类组合被作为一个整体处理。统一单位映射:
用字典管理所有单位对应的倍数,不管是缩写(k/m/b)还是完整单词(thousand/million),都能快速找到对应的换算值,后续扩展单位也方便。分场景处理逻辑:
- 先判断是否是数字+缩写的格式,提取数字部分后乘倍数;
- 再处理数字+单位单词的格式,拆分数字和单词后计算;
- 兼容带逗号的数字格式(如1,234),转换时替换逗号为点避免报错;
- 最后处理纯数字单词,用
word2number转换。
修复原代码错误:
原代码中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
相关产品推荐
相关产品推荐

