首页 > 解决方案 > 如果不匹配,正则表达式会跳过值

问题描述

我正在使用以下正则表达式从文件中提取数据,只要提取的数据包含正则表达式的所有 3 个元素,它就可以正常工作,如果不是(如果只有一个是混乱的)正则表达式只是跳过数据,怎么办我将此行为更改为不跳过不匹配的值,而是用 0 或 null 填充它?

bC_NUMBER = 1
bS_ID = 1
bTRANSACTION_AMOUNT = 1
rC_NUMBER = r"number:\s(\d+\*+\d+).*?"
rS_ID = r"ID:\s*(\d*).*?"
rT_ID = r"ATM:\s(\w+).*?"
rT_AMOUNT = r"Total cash dispensed:\s*([a-zA-Z0-9]+)\s+([a-zA-Z0-9]+).*?"

regex = rC_NUMBER*bC_NUMBER+ rS_ID*bS_ID + rT_AMOUNT*bTRANSACTION_AMOUNT

示例输出:

[('99280*********8823', '182', '40000', 'MGA'), ('99280*********8823', '182', '40000', 'MGA')]

期望的输出:

[('99280*********8823', '182', '40000', 'MGA'),('6700*********8823', '177', 'null or 0', 'null or 0'), ('99280*********8823', '182', '40000', 'MGA')]

标签: pythonregex

解决方案


您可以使用正则表达式

(?s)Card number:\s(\d+\*+\d+)(?:(?!Card number:).)*?ID:\s*(\d*)(?:(?:(?!Card number:).)*?Total cash dispensed:\s*([a-zA-Z0-9]+)\s+([a-zA-Z0-9]+))?

请参阅正则表达式演示

注意:1).*?变成了一个(?:(?!Card number:).)*?调和的贪婪令牌,2)如果现在是可选的,最后一部分(?:(?:(?!Card number:).)*?Total cash dispensed:\s*([a-zA-Z0-9]+)\s+([a-zA-Z0-9]+))?,和3)我正在使用(?s)(在代码中,re.Sre.DOTALL),以便.可以匹配任何字符,包括换行符。

请参阅Python 演示

import re
 
test_str = "YOUR_STRING_HERE"
 
bC_NUMBER = 1
bS_ID = 1
bTRANSACTION_AMOUNT = 1
rC_NUMBER = r"Card number:\s(\d+\*+\d+)"
rS_ID = r"(?:(?!Card number:).)*?ID:\s*(\d*)"
rT_ID = r"(?:(?!Card number:).)*?ATM:\s(\w+)"
rT_AMOUNT = r"(?:(?:(?!Card number:).)*?Total cash dispensed:\s*([a-zA-Z0-9]+)\s+([a-zA-Z0-9]+))?"
 
regex = rC_NUMBER*bC_NUMBER+ rS_ID*bS_ID + rT_AMOUNT*bTRANSACTION_AMOUNT
print( re.findall(regex, test_str, re.S) )

输出:

[('99280*********8823', '182', '40000', 'MGA'), ('6700*********8823', '177', '', ''), ('99280*********8823', '182', '40000', 'MGA')]

推荐阅读