如何遍历单词列表并通过正则提取对应数字?
解决水果成本数字提取的正则问题
错误原因解析
re.error: look-behind requires fixed-width pattern:Python标准库re的正向预查(lookbehind)默认要求匹配模式为固定长度,你将长度不一的水果单词用|拼接后,模式长度不固定,因此触发该错误。TypeError: can only concatenate str (not "list") to str:你的regex_fruit_cost函数仅接受字符串参数,直接传入列表会导致字符串拼接失败。
方案1:遍历水果列表逐个匹配(最兼容、易实现)
既然单个单词匹配正常,直接遍历水果列表,为每个单词单独生成正则并提取对应数字即可,完全规避lookbehind长度限制问题。
import re def regex_fruit_cost(subst): # 用re.escape处理水果名,避免特殊正则字符干扰;将*改为+确保匹配至少一个数字 return r"(?<=" + re.escape(subst) + r").*?(?P<number>[0-9,.]+)" fruit_words = ['Appels', 'Ananas', 'Peen Waspeen', 'Tomaten Cherry', 'Sinaasappels', 'Watermeloenen', 'Rettich', 'Peren', 'Peen', 'Mandarijnen', 'Meloenen', 'Grapefruit'] # 示例输入文本 sample_text = """Appels 1,23 Ananas 4.56 Peen Waspeen 78,90 Tomaten Cherry 123.45 Sinaasappels 67,89""" # 遍历提取所有水果对应的数字 fruit_costs = {} for fruit in fruit_words: pattern = regex_fruit_cost(fruit) matches = re.finditer(pattern, sample_text) for match in matches: cost = match.group('number').strip() if cost: fruit_costs[fruit] = cost print(fruit_costs)
方案2:Python 3.7+可变长度lookbehind(单次匹配)
Python 3.7开始支持有限的可变长度lookbehind(模式长度需有上限),可一次性匹配所有水果,需额外处理水果名的对应关系:
import re # 先按长度倒序排序水果列表,避免短名称优先匹配(比如"Peen"和"Peen Waspeen") sorted_fruits = sorted(fruit_words, key=lambda x: -len(x)) # 生成拼接后的水果模式,用re.escape转义特殊字符 fruit_pattern = '|'.join(re.escape(f) for f in sorted_fruits) # 构建可变长度lookbehind的正则 pattern = fr"(?<={fruit_pattern}).*?(?P<number>[0-9,.]+)" sample_text = """Appels 1,23 Ananas 4.56 Peen Waspeen 78,90 Tomaten Cherry 123.45 Sinaasappels 67,89""" fruit_costs = {} for match in re.finditer(pattern, sample_text): cost = match.group('number').strip() # 反向匹配找到对应的水果名 for fruit in sorted_fruits: if sample_text[match.start() - len(fruit):match.start()] == fruit: fruit_costs[fruit] = cost break print(fruit_costs)
推荐说明
优先选择方案1,无需依赖Python版本,逻辑简单易懂,也不会出现水果名重叠导致的匹配优先级问题。
内容的提问来源于stack exchange,提问作者mightycode Newton
相关产品推荐
相关产品推荐

