如何用Python从文本中提取漫画系列及期号并格式化输出?
漫画系列与期号提取格式化的Python实现
你需要从单行文本中提取漫画系列和对应期号,还要处理#nn替换为#00、展开期号范围、避免非数字期号报错的问题,以下是可行的实现代码:
import re def parse_comic_issues(text): # 匹配漫画系列名及对应的所有期号块,直到下一个系列出现 comic_pattern = re.compile( r'([A-Za-z\s-]+?)\s*(#?[\d-n,-]+(?:,\s*#?[\d-n,-]+)*)(?=,\s*[A-Z]|$)', re.IGNORECASE ) comic_matches = comic_pattern.finditer(text) comic_dict = {} for match in comic_matches: series_name = match.group(1).strip() issues_raw = match.group(2).strip() # 拆分单个期号项 issue_items = [item.strip() for item in issues_raw.split(',')] processed_issues = [] for item in issue_items: # 处理#nn替换为#00的情况 if item == '#nn': processed_issues.append('#00') continue # 处理期号范围(如368-369、#13-17) if '-' in item: start_part, end_part = item.split('-', 1) start_part = start_part.strip() end_part = end_part.strip() # 提取期号前缀(#或空) prefix = '#' if start_part.startswith('#') else '' # 剥离前缀后的数字部分 start_num = start_part.lstrip('#') end_num = end_part.lstrip('#') # 仅当两端都是数字时展开范围,避免ValueError if start_num.isdigit() and end_num.isdigit(): start_int = int(start_num) end_int = int(end_num) # 生成范围内的所有期号 for num in range(start_int, end_int + 1): processed_issues.append(f'{prefix}{num}') else: # 非数字范围直接保留原项(如遇到nn-xx这类特殊格式) processed_issues.append(item) else: # 单个期号,处理孤立的nn(示例中未出现,做兼容) if item == 'nn': processed_issues.append('00') else: processed_issues.append(item) # 合并同一系列的期号 if series_name in comic_dict: comic_dict[series_name].extend(processed_issues) else: comic_dict[series_name] = processed_issues # 格式化输出结果 output_lines = [] for series, issues in comic_dict.items(): output_lines.append(f'*{series}*: {", ".join(issues)}') return '\n'.join(output_lines) # 测试示例1 text1 = "Batman #323, 325, 335, 340, 368-369, 397-400, Amazing Spider-Man #13-17" print(parse_comic_issues(text1)) print("\n---\n") # 测试示例2 text2 = "Amazing Spider-Man #nn, Amazing Spider-Man Annual #10, Amazing Spider-Man 174, 185, 213, 245, 326" print(parse_comic_issues(text2))
代码说明
- 正则匹配逻辑:精准定位每个漫画系列及其关联的所有期号,通过
(?=,\s*[A-Z]|$)断言确保只匹配到下一个系列开头或文本结束,避免跨系列匹配。 - 期号处理:
- 直接替换
#nn为#00; - 仅当范围两端都是数字时展开,避免非数字输入触发
ValueError; - 保留期号的
#前缀格式,确保输出和原文本格式一致;
- 直接替换
- 合并同系列:自动将分散的同系列期号(如示例2中多次出现的
Amazing Spider-Man)合并到一起。
测试输出
示例1输出:
Batman: #323, 325, 335, 340, #368, #369, #397, #398, #399, #400
Amazing Spider-Man: #13, #14, #15, #16, #17
示例2输出:
Amazing Spider-Man: #00, 174, 185, 213, 245, 326
Amazing Spider-Man Annual: #10
内容的提问来源于stack exchange,提问作者isatiger
相关产品推荐
相关产品推荐

