文本处理:从字符串列表提取指定字段构建DataFrame时正则异常的解决
原代码错误根因
- 列表结构适配错误:
content_list内的实体被拆分为2个连续的独立元素:奇数索引元素仅存储Seq. #标签和对应数值,无其他目标字段;偶数索引元素存储同一实体的剩余全部字段。原循环逐元素单独做正则拆分,处理仅存Seq值的孤立列表项时,split后得到的片段列表长度仅为1,直接访问后续下标就会触发越界。 - 字段顺序错配:原
re.split分割后的片段顺序,和DataFrame定义的列顺序不匹配——分割得到的片段顺序为Seq值、Name值、Target Value值、Selections值、Supporting Definitions值、Coding Instructions值,但原代码赋值时将下标2(Target Value值)对应给了Coding Instructions列、下标4(Supporting Definitions值)对应给了Target Value列,存在严重的字段张冠李戴。 - 索引越界风险:部分实体的
Coding Instructions字段无后续有效内容,分割后得到的片段列表长度不足6,直接访问metadata[5]时就会触发越界报错。
修正后可运行代码
import re import pandas as pd # 配对合并被拆分的相邻条目(原列表每2个元素对应1条完整实体) full_records = [] for idx in range(0, len(content_list), 2): record_text = content_list[idx] + content_list[idx+1] full_records.append(record_text) # 带命名捕获组的正则,一次性匹配所有目标字段 field_pattern = re.compile( r"Seq\. #:\s*(?P<seq_num>\d+)" r"Name:\s*(?P<name>.*?)" r"Target Value:\s*(?P<target_value>.*?)" r"Selections:\s*(?P<selections>.*?)" r"Supporting Definitions:\s*(?P<support_def>.*?)" r"Coding Instructions:\s*(?P<coding_inst>.*?)" r"(?:Note\(s\):|$)", re.DOTALL ) # 逐记录提取字段,匹配失败自动补空值 extracted_data = [] for text in full_records: match = field_pattern.search(text) if match: clean_record = {k: v.strip() for k, v in match.groupdict().items()} extracted_data.append([ clean_record['seq_num'], clean_record['name'], clean_record['coding_inst'], clean_record['target_value'], clean_record['selections'], clean_record['support_def'] ]) else: extracted_data.append([None]*6) # 生成符合要求结构的DataFrame df = pd.DataFrame( extracted_data, columns=['Seq. #', 'Name', 'Coding Instructions', 'Target Value', 'Selections', 'Supporting Definitions'] ) # Seq. #字段做类型转换,兼容异常值 df['Seq. #'] = pd.to_numeric(df['Seq. #'], errors='coerce').astype('Int64')
修正逻辑说明
- 相邻元素配对合并:按步长2遍历原列表,将存储Seq值的孤立元素和后续存储剩余字段的元素拼接为单条完整实体文本,为正则匹配提供完整上下文,从根源解决孤立元素导致的索引越界问题。
- 命名捕获组替代无序split:通过带分组名的正则直接定位每个目标字段的内容,按字段名读取匹配结果,不依赖split后的片段下标顺序,彻底避免字段张冠李戴。
- 异常兜底:对正则匹配失败的记录自动填充空值;Seq. #字段转换时加入错误兼容,避免非数值内容中断程序运行。
内容的提问来源于stack exchange,提问作者Adri
相关产品推荐
相关产品推荐

