单字符分数(如½)检测及转换为结构化信息的技术需求
解决方案:提取文本中的分数并转为结构化信息
嘿,这个提取分数并结构化的需求我刚好有成熟的方案,咱们一步步来实现,完全满足你「按字面提取、不化简分数」的要求:
核心思路
首先得区分两种需要处理的分数形式,针对性做匹配和转换:
- 单字符分数:比如
½、¾这类预编码的Unicode字符,我们需要先建立一个映射表,直接对应到分子和分母; - 文本型分数:比如
3/9、5/2这类用斜杠分隔的数字组合,用正则表达式精准匹配,确保提取到的分子分母完全保留原始值。
另外还要覆盖两种场景:分数和整数组合(比如32 ½)、单独存在的分数(比如⅞或4/6)。
示例代码(Python实现)
下面是可直接运行的代码,逻辑清晰,注释也写得很明白:
import re # 单字符分数→分子/分母的映射表,覆盖绝大多数常见分数字符,完全按字面对应 fraction_char_map = { '½': (1, 2), '¼': (1, 4), '¾': (3, 4), '⅛': (1, 8), '⅜': (3, 8), '⅝': (5, 8), '⅞': (7, 8), '⅓': (1, 3), '⅔': (2, 3), '⅕': (1, 5), '⅖': (2, 5), '⅗': (3, 5), '⅘': (4, 5), '⅙': (1, 6), '⅚': (5, 6), '⅐': (1, 7), '⅑': (1, 9), '⅒': (1, 10) } def extract_and_structurize(text): structured_results = [] # 1. 匹配「整数 + 单字符分数」的情况(比如32 ½) char_fraction_with_int = re.compile(r'(\d+)\s*([{}])'.format(''.join(fraction_char_map.keys()))) for match in char_fraction_with_int.finditer(text): integer = match.group(1) num, den = fraction_char_map[match.group(2)] structured_results.append(f"info: {integer}, numerator = {num}, denominator = {den}") # 2. 匹配「整数 + 文本型分数」的情况(比如15 3/9) text_fraction_with_int = re.compile(r'(\d+)\s*(\d+)/(\d+)') for match in text_fraction_with_int.finditer(text): integer = match.group(1) num = match.group(2) den = match.group(3) structured_results.append(f"info: {integer}, numerator = {num}, denominator = {den}") # 3. 匹配单独的单字符分数(比如⅞) standalone_char_fraction = re.compile(r'\b([{}])\b'.format(''.join(fraction_char_map.keys()))) for match in standalone_char_fraction.finditer(text): num, den = fraction_char_map[match.group(1)] structured_results.append(f"info: None, numerator = {num}, denominator = {den}") # 4. 匹配单独的文本型分数(比如4/6) standalone_text_fraction = re.compile(r'\b(\d+)/(\d+)\b') for match in standalone_text_fraction.finditer(text): num = match.group(1) den = match.group(2) structured_results.append(f"info: None, numerator = {num}, denominator = {den}") return structured_results # 测试用例 test_text = "32 ½ is not very hot, but 15 3/9 is cooler, and ⅞ is just right" for result in extract_and_structurize(test_text): print(result)
关键细节说明
- 正则里的
\b是单词边界,用来避免误匹配比如123/456abc这种非独立分数的情况;如果你的文本里分数和其他字符连在一起,可以调整边界规则; - 映射表完全按字面对应,比如
⅑直接映射为(1,9),不会做任何约分处理; - 代码覆盖了所有可能的分数出现场景,你可以根据自己的文本特点,增减映射表中的字符或者调整正则规则。
内容的提问来源于stack exchange,提问作者Ed Z
相关产品推荐
相关产品推荐

