使用Regex、strptime和Lambda Apply转换多格式日期失败排查
解决日期转换报错及格式统一问题
问题原因
你的代码出现unconverted data remains错误的核心原因有两个:
- 正则匹配顺序错误:带时间的日期格式正则放在了短日期格式之后,导致
2023-07-26 12:46:21先被\d{4}-\d{2}-\d{2}匹配到开头的日期部分,随后用%Y-%m-%d解析整个字符串时,剩余的时间部分无法转换。 - 正则未限制匹配范围:
re.match仅从字符串开头匹配,没有确保匹配整个字符串,导致部分匹配后就触发解析逻辑。
解决方案
调整正则顺序、完善匹配规则,并将最终结果格式化为%Y-%m-%d字符串:
from datetime import datetime import re import pandas as pd def conv_date(dte: str) -> str: # 把更长、更具体的格式放在最前面 acceptable_mappings = { r"\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}": "%Y-%m-%d %H:%M:%S", r"\d{4}-\d{2}-\d{2}": "%Y-%m-%d", r"\d{2}-\d{2}-\d{4}": "%d-%m-%Y", r"\d{4}/\d{2}/\d{2}": "%Y/%m/%d", r"\d{2}/\d{2}/\d{4}": "%d/%m/%Y", r"\d{8}": '%d%m%Y', r"\d{2}\s\d{2}\s\d{4}": '%d %m %Y', } for regex, fmt in acceptable_mappings.items(): # 用fullmatch确保匹配整个字符串,避免部分匹配 if re.fullmatch(regex, dte): dt = datetime.strptime(dte, fmt) # 格式化为目标日期字符串 return dt.strftime("%Y-%m-%d") raise Exception(f"Expected date in one of supported formats, got {dte}") mock_dict = [ {"name": "dz", "role": "legend", "date": "2023-07-26"}, {"name": "mc", "role": "sounds like a dj", "date": "26-07-2023"}, {"name": "xc", "role": "loves xcom", "date": "2023/07/26"}, {"name": "lz", "role": "likes a to fly", "date": "26/07/2023"}, {"name": "wc", "role": "has a small bladder", "date": "26072023"}, {"name": "aa", "role": "warrior of the crystal", "date": "26 07 2023"}, {"name": "xx", "role": "loves only-fans", "date": "2023-07-26 12:46:21"}, ] df = pd.DataFrame(mock_dict) if __name__ == "__main__": print("原始数据:") print(df) df['date_clean'] = df['date'].apply(conv_date) print("\n处理后数据:") print(df)
关键修改点
- 调整正则顺序:将包含时间的日期格式放在最前面,优先匹配更复杂的格式。
- 使用
re.fullmatch:替代re.match,确保正则匹配整个字符串,避免部分匹配导致的解析错误。 - 返回格式化字符串:将解析后的datetime对象用
strftime("%Y-%m-%d")转换为目标格式的字符串,符合期望输出。
运行结果
执行后会输出符合预期的表格,所有日期统一为%Y-%m-%d格式,带时间的日期也能正确提取日期部分并转换。
内容的提问来源于stack exchange,提问作者Mizanur Choudhury
相关产品推荐
相关产品推荐

