正则匹配提取完整交易行:处理公司名中的换行符问题
问题
有一个不可控生成机制产生的字符串,公司名称中间存在\n换行符,需要实现两个目标:
- 把公司名里的
\n替换为空格 - 提取每一条完整的交易记录行
原始字符串片段:
\nGBP*\nAA1234567 A random company name - I 03-Mar-2023 BUY 42.6400 42.6900 GBP 1,820.3016 1.0000 1,842.4400\nAA1234568 Another randon company name - H-M 03-Mar-2023 BUY 11.9880 845.6000 GBP 10,137.0528 1.0000 10,159.1700\nAA12345679 Third Party Utilies - Fund - Class\nAA-B Income\n03-Mar-2023 BUY 6.4120 836.9100 GBP 5,366.2669 1.0000 5,388.5200\nAA12345670 Company 4 - M 03-Mar-2023 BUY 205.6830 10.8500 GBP 2,231.6606 1.0000 2,253.7800\nAA2345678 Another random page up company - I 03-Mar-2023 BUY 66.3850 45.4400 GBP 3,016.5344 1.0000 3,038.6500\nASSET SCHEDULE\nPolicy Number 1234-56789\nAA2345679 Company 5 Utilities- M 03-Mar-2023 BUY 76.7370 13.7400 GBP 1,054.3664 1.0000 1,076.4900\nTotal
期望提取结果:
AA1234567 A random company name - I 03-Mar-2023 BUY 42.6400 42.6900 GBP 1,820.3016 1.0000 1,842.4400 AA1234568 Another random company name - H-M 03-Mar-2023 BUY 11.9880 845.6000 GBP 10,137.0528 1.0000 10,159.1700 AA12345679 Third Party Utilities - Fund - Class AA-B Income 03-Mar-2023 BUY 6.4120 836.9100 GBP 5,366.2669 1.0000 5,388.5200 AA12345670 Company 4 - M 03-Mar-2023 BUY 205.6830 10.8500 GBP 2,231.6606 1.0000 2,253.7800 AA2345678 Another random page up company - I 03-Mar-2023 BUY 66.3850 45.4400 GBP 3,016.5344 1.0000 3,038.6500 AA2345679 Company 5 Utilities- M 03-Mar-2023 BUY 76.7370 13.7400 GBP 1,054.3664 1.0000 1,076.4900
现有正则问题:
使用正则模式 (?<=\\n).*?([a-zA-Z]{3})-(\d{4}) 无法提取完整交易行,缺少数值部分且包含无关内容。
解决方案
可以分两步处理,先修复跨行的公司名,再提取交易行:
步骤1:修复跨行的公司名(替换换行为空格)
识别交易行内的换行(非交易行开头的换行),将其替换为空格:
- 交易行起始特征:以
AA开头+一串数字(如AA1234567) - 正则替换规则:
查找:\n(?!AA\d+)
替换为:
该正则含义:匹配所有\n,但排除掉紧跟AA+数字的换行(即交易行的开头换行),仅替换公司名内的换行。
步骤2:提取完整交易行
修复后的字符串中,交易行以AA+数字开头,直到下一个交易行或无关内容(如ASSET SCHEDULE、Total)结束。使用以下正则提取:
- 提取正则:
AA\d+.*?(?=\nAA\d+|\nASSET SCHEDULE|\nTotal) - 开启单行模式(
s修饰符),确保.能匹配所有字符(含换行,不过步骤1已替换交易内换行,不加也可)
完整处理示例(Python代码)
import re original_str = "\nGBP*\nAA1234567 A random company name - I 03-Mar-2023 BUY 42.6400 42.6900 GBP 1,820.3016 1.0000 1,842.4400\nAA1234568 Another randon company name - H-M 03-Mar-2023 BUY 11.9880 845.6000 GBP 10,137.0528 1.0000 10,159.1700\nAA12345679 Third Party Utilies - Fund - Class\nAA-B Income\n03-Mar-2023 BUY 6.4120 836.9100 GBP 5,366.2669 1.0000 5,388.5200\nAA12345670 Company 4 - M 03-Mar-2023 BUY 205.6830 10.8500 GBP 2,231.6606 1.0000 2,253.7800\nAA2345678 Another random page up company - I 03-Mar-2023 BUY 66.3850 45.4400 GBP 3,016.5344 1.0000 3,038.6500\nASSET SCHEDULE\nPolicy Number 1234-56789\nAA2345679 Company 5 Utilities- M 03-Mar-2023 BUY 76.7370 13.7400 GBP 1,054.3664 1.0000 1,076.4900\nTotal" # 修复跨行公司名 fixed_str = re.sub(r'\n(?!AA\d+)', ' ', original_str) # 提取所有交易行 transactions = re.findall(r'AA\d+.*?(?=\nAA\d+|\nASSET SCHEDULE|\nTotal)', fixed_str, re.DOTALL) # 输出结果 for tx in transactions: print(tx.strip())
逻辑说明
- 替换阶段:精准区分交易行之间的换行和公司名内的换行,只替换后者为空格,保证交易行结构清晰。
- 提取阶段:通过正向预查限定交易行的结束位置,确保提取到从交易行开头到下一个交易行或无关内容前的完整信息。
内容的提问来源于stack exchange,提问作者Anthony
相关产品推荐
相关产品推荐

