如何从不同格式的日期时间字符串中提取时间并保留原格式?
提取日期时间字符串中的时间部分并保留原格式
要解决这个问题,核心思路是先识别整个日期时间字符串的格式,再提取对应格式的时间部分;如果无法精准匹配格式,就通过正则或兜底方式提取最接近原格式的时间。下面是具体的实现方案,用Python为例:
方法思路
- 预定义常见格式组合:先列出常用的日期格式和时间格式,生成所有可能的日期时间组合格式,尝试用
datetime.strptime解析输入字符串——如果匹配成功,直接用对应的时间格式提取时间。 - 备用方案:自动解析+正则匹配:如果预定义格式没覆盖到,用
dateutil.parser自动解析日期时间,再通过正则匹配原字符串中的时间子串,保证格式和原输入一致。 - 兜底处理:如果以上都失败,就拆分字符串取后半部分(默认时间在日期之后)。
代码实现
import datetime import re def extract_time_with_original_format(datetime_str): # 第一步:尝试匹配预定义的日期时间格式组合 date_formats = [ '%Y-%m-%d', '%Y/%m/%d', '%Y.%m.%d', '%d-%m-%Y', '%d/%m/%Y', '%d.%m.%Y', '%m-%d-%Y', '%m/%d/%Y', '%m.%d.%Y', '%Y%m%d', '%d%m%Y', '%m%d%Y' ] time_formats = [ '%H:%M:%S', '%H:%M', '%I:%M %p', '%I:%M:%S %p', '%H:%M:%S.%f', '%I:%M:%S.%f %p' ] # 生成带空格和带T的组合格式(比如2010-10-23T01:02:45这种ISO格式) combined_formats = [f"{df} {tf}" for df in date_formats for tf in time_formats] combined_formats.extend([f"{df}T{tf}" for df in date_formats for tf in time_formats]) for fmt in combined_formats: try: dt_obj = datetime.datetime.strptime(datetime_str, fmt) # 提取时间部分的格式规则 time_fmt = fmt.split(' ')[-1] if ' ' in fmt else fmt.split('T')[-1] # 用原时间格式输出 return dt_obj.strftime(time_fmt) except ValueError: continue # 第二步:用dateutil自动解析 + 正则匹配原时间子串 try: from dateutil import parser dt_obj = parser.parse(datetime_str) # 正则匹配常见时间格式(按复杂度从高到低匹配) time_patterns = [ r'\d{1,2}:\d{2}:\d{2}\.\d+ [APM]{2}', # 带毫秒的12小时制(如1:05:30.123 AM) r'\d{2}:\d{2}:\d{2}\.\d+', # 带毫秒的24小时制 r'\d{1,2}:\d{2}:\d{2} [APM]{2}', # 12小时制带秒 r'\d{2}:\d{2}:\d{2}', # 24小时制带秒 r'\d{1,2}:\d{2} [APM]{2}', # 12小时制(如1:05 AM) r'\d{2}:\d{2}' # 24小时制(如13:45) ] for pattern in time_patterns: match_result = re.search(pattern, datetime_str, re.IGNORECASE) if match_result: return match_result.group() # 如果正则没匹配到,返回最接近原格式的时间字符串 return dt_obj.strftime('%I:%M %p') if dt_obj.hour <= 12 else dt_obj.strftime('%H:%M:%S') except ImportError: print("提示:需要安装python-dateutil库(pip install python-dateutil)以启用自动解析功能") except Exception: pass # 第三步:兜底处理,取字符串后半部分 split_parts = datetime_str.split() if len(split_parts) >= 2: return ' '.join(split_parts[1:]) return datetime_str # 测试你的例子 print(extract_time_with_original_format("2010-10-23 01:02:45")) # 输出: 01:02:45 print(extract_time_with_original_format("2010/1/23 1:05 AM")) # 输出: 1:05 AM
注意事项
- 如果你用的是Python3.7+,
datetime.fromisoformat可以直接解析ISO格式的日期时间(如2010-10-23T01:02:45),但上面的代码已经覆盖了这种情况。 python-dateutil是第三方库,需要先安装:pip install python-dateutil,它能处理更多非常规的日期时间格式。- 如果你的输入有非常罕见的时间格式,可以自行扩展
time_formats列表或正则time_patterns来适配。
内容的提问来源于stack exchange,提问作者pad0n




