替代正则+条件语句的多类型结构化数据Python解析方案咨询
数据集解析方案优化
数据集格式说明
现有数据集每行包含以下8种格式:
name1: float(纯浮点数值)name2: float [unit](带单位的浮点数值)name3: {str: float [unit], (...repeat)}(键值对集合)name4: datetime(日期时间格式)name5: int(整数)name6: alphanumeric(字母数字混合ID)name7: strings (sentence/phrase)(句子/短语字符串)name8: {{...can contain any of above but we ignore..}}(嵌套大括号内容,直接忽略)
当前解析问题
现有正则+条件语句的解析代码存在以下缺陷:
- 无法处理
{...}格式的键值对集合行 - 会将字母数字混合的ID误识别为数值类型
- 需要大量硬编码条件才能覆盖所有格式场景
现有解析代码:
PATTERN_GENERIC = r'(?P<name>[^,:]*)(,|:)\s?(?P<content>.*)' PATTERN_VALUE = r'(?P<name>[^:]*)[^0-9-]*(?P<content>[-+]?\d*\.\d+|\d+)' header = {} with open(f) as fopen: for line in fopen: # parse number only results = re.search(PATTERN_VALUE,line.strip('\n')) if results: h = results.groupdict() header[h['name'].replace(' ','')] = float(h['content']) else: #treat as ID results = re.search(PATTERN_GENERIC,line.strip('\n')) if results: h = results.groupdict() header[h['name'].replace(' ','')] = h['content']
优化方案
方案一:分层结构化解析
通过预处理分类+针对性解析,解决格式兼容问题,最终输出包含name和content的结构化数据:
import re from datetime import datetime def parse_single_line(line): line = line.strip() # 直接跳过需忽略的嵌套大括号行 if line.startswith('{{'): return None # 拆分名称与内容(匹配第一个:作为分隔符,避免误拆内容中的冒号) name_content_match = re.match(r'^(?P<name>[^:]+):\s*(?P<content>.+)$', line) if not name_content_match: return None name = name_content_match.group('name').strip().replace(' ', '') content = name_content_match.group('content').strip() # 解析{...}格式的键值对集合 if content.startswith('{') and content.endswith('}'): inner_content = content[1:-1].strip() parsed_dict = {} if inner_content: # 拆分集合内的键值对(兼容嵌套括号场景) kv_pairs = re.split(r',\s*(?![^(){}]*\})', inner_content) for kv in kv_pairs: k, v = re.split(r':\s*', kv, maxsplit=1) # 解析带单位的数值 unit_num_match = re.match(r'([-+]?\d*\.\d+|\d+)\s*\[(.+)\]', v) if unit_num_match: num_str = unit_num_match.group(1) parsed_dict[k.strip()] = { 'value': float(num_str) if '.' in num_str else int(num_str), 'unit': unit_num_match.group(2) } else: parsed_dict[k.strip()] = v.strip() return {'name': name, 'content': parsed_dict} # 解析带单位的数值 unit_match = re.match(r'([-+]?\d*\.\d+|\d+)\s*\[(.+)\]', content) if unit_match: num_str = unit_match.group(1) num = float(num_str) if '.' in num_str else int(num_str) return {'name': name, 'content': {'value': num, 'unit': unit_match.group(2)}} # 解析纯数值(整数/浮点数) pure_num_match = re.fullmatch(r'[-+]?\d*\.\d+|\d+', content) if pure_num_match: num_str = pure_num_match.group() return {'name': name, 'content': float(num_str) if '.' in num_str else int(num_str)} # 解析日期时间(支持多种常见格式,可按需扩展) try: dt_formats = ['%Y-%m-%d %H:%M:%S', '%Y-%m-%d', '%H:%M:%S'] for fmt in dt_formats: dt = datetime.strptime(content, fmt) return {'name': name, 'content': dt} except ValueError: pass # 剩余情况直接返回原始内容(字母数字ID/字符串) return {'name': name, 'content': content} # 解析整个文件 def parse_dataset(file_path): parsed_result = [] with open(file_path, 'r', encoding='utf-8') as f: for line in f: line_result = parse_single_line(line) if line_result: parsed_result.append(line_result) return parsed_result # 使用示例 # final_data = parse_dataset("your_data_file.txt")
方案二:预处理为CSV后用Pandas解析
如果偏好类似pd.read_csv的使用方式,可以先将原始文件预处理为标准CSV格式,再用Pandas读取并做类型转换:
# 预处理脚本:将每行转换为CSV行 def preprocess_to_csv(input_path, output_path): with open(input_path, 'r', encoding='utf-8') as infile, open(output_path, 'w', encoding='utf-8') as outfile: outfile.write('name,content\n') for line in infile: line = line.strip() if line.startswith('{{'): continue # 拆分名称与内容 parts = line.split(':', 1) if len(parts) != 2: continue name = parts[0].strip().replace(' ', '') content = parts[1].strip() # CSV格式转义(处理含逗号或引号的内容) if ',' in content or '"' in content: content = f'"{content.replace('"', '""")}"' outfile.write(f'{name},{content}\n') # 预处理后用Pandas读取并解析 # preprocess_to_csv("your_data_file.txt", "processed_data.csv") # import pandas as pd # df = pd.read_csv("processed_data.csv") # # 后续可对df['content']列应用方案一中的解析逻辑做类型转换
核心优化点
- 精准拆分:用正则匹配第一个
:作为名称与内容的分隔,避免误拆内容中的冒号 - 分层判断:按格式优先级依次解析集合、带单位数值、纯数值、日期,最后兜底处理字符串
- 避免误判:只有当内容完全匹配数值格式时才识别为数值,解决字母数字ID被误判的问题
- 可扩展性:日期格式、集合嵌套规则可按需扩展,无需大量硬编码
内容的提问来源于stack exchange,提问作者Hello World
相关产品推荐
相关产品推荐

