如何使用Python解析存储过程中的变量值
问题分析
你当前使用固定字符串偏移量切片提取参数的方案稳定性极差,只要邮件正文的换行、前缀后缀内容长度发生变化,切片结果就会完全失效。最可靠的实现方式是通过正则表达式匹配存储过程的结构化语法,直接提取对应位置的参数,完全不依赖字符位置。
实现方案
针对你给出的存储过程调用格式,我们预编译正则规则分别定位三个参数的位置:
- 第一个入参(证券代码):匹配
INSERTEQCLOSINGPRICE(后第一个双引号包裹的字符串 - 第二个入参(交易日期):匹配
TEXT()函数内传入的YYYY-MM-DD格式日期 - 第三个入参(收盘价):匹配to_date参数后第一个双引号包裹的浮点数值
改造后代码
import win32com.client import re import datetime as dt # 基础配置 EMAIL_SUBJ_SEARCH_STRING = 'SGEPSBSH Index Level' # 预编译正则匹配规则,一次匹配提取三个目标参数 PROC_MATCH_PATTERN = re.compile( r'INSERTEQCLOSINGPRICE\("([^"]+)",to_date\(\'\"&TEXT\((\d{4}-\d{2}-\d{2}),"DDMMMYYYY"\)&"\',\'ddmonyyyy\'\),"([\d.]+)",NULL,NULL\);' ) result_set = {'Ticker': [], 'TickerLevel': [], 'DATE': []} # 初始化Outlook连接 out_app = win32com.client.gencache.EnsureDispatch("Outlook.Application") out_namespace = out_app.GetNamespace("MAPI") root_folder = out_namespace.GetDefaultFolder(6) target_folder = root_folder.Folders['Email_Snapper'] # 可选:开启时间过滤减少遍历范围 # filter_time = (dt.datetime.now() - dt.timedelta(days=3)).strftime('%m/%d/%Y %H:%M %p') # target_folder = target_folder.Restrict(f"[ReceivedTime] >= '{filter_time}'") mail_count = target_folder.Items.Count if mail_count > 0: # 倒序遍历优先取最新邮件 for mail_idx in range(mail_count, 0, -1): mail = target_folder.Items[mail_idx] if EMAIL_SUBJ_SEARCH_STRING in mail.Subject: # 截取正文到Regards位置,兼容原有逻辑 mail_body = mail.Body.strip() if "Regards" in mail_body: mail_body = mail_body[:mail_body.find("Regards")].strip() # 执行正则匹配 match_result = PROC_MATCH_PATTERN.search(mail_body) if not match_result: print(f"未匹配到符合格式的存储过程,正文片段:{mail_body[:300]}") break ticker, trade_date_str, price_str = match_result.groups() # 类型转换后存入结果集 result_set['Ticker'].append(ticker) result_set['TickerLevel'].append(float(price_str)) result_set['DATE'].append(dt.datetime.strptime(trade_date_str, "%Y-%m-%d").date()) print(f"解析结果:\n证券代码:{ticker}\n交易日期:{trade_date_str}\n收盘价:{price_str}") # 取到最新1封符合条件的邮件后终止遍历 break
方案优势
- 鲁棒性强:只要存储过程的参数顺序、基础语法结构不变,无论邮件正文前后新增多少内容,都不会影响参数提取结果
- 自带校验:匹配失败时会打印正文片段方便排查问题,避免切片方式下静默返回错误值的问题
- 自动类型转换:直接输出浮点型价格、日期型交易日期,不需要后续额外做格式处理
- 性能更好:去掉了不必要的pandas转换逻辑,减少冗余计算
内容的提问来源于stack exchange,提问作者Rahul Vaidya
相关产品推荐
相关产品推荐

