优化正则表达式,精准捕获item块中ID、Name、DataSetList值
问题描述
我正尝试从存储信息的文件中捕获变量值,但面临换行和空格的问题。例如,DataSetList变量存在两种存储形式:
输入示例
Templates = < item Name = 'fruits' TemplateList = '7,12' end> Surveys = < item ID = 542 Name = 'apple' end item ID = 872 Name = 'banana' DataSetList = '873,887,971,1055' PluginInfo = {something} end item ID = 437 Name = 'cherry' DataSetList = '438,452,536,620,704,788,1143,1179,1563,1647,1731,1839,1875,1851,' + '1863,2060,2359,2443,2469,2620' PluginInfo = {something} end>
我目前使用的正则表达式可以捕获item-end块中的ID、Name、DataSetList变量值:
当前正则表达式
ID[\s\=]*(?P<UID>\d*)\s*Name[\s\=]*'(?P<Name>.*)'\s*DataSetList[\s\=]*(?P<DataSetList>(?:'[\d\,]*'[\s\+]*)*)
拆分解释:
ID[\s\=]*(?P<UID>\d*) # 捕获ID \s* # 匹配空格 Name[\s\=]*'(?P<Name>.*)' # 捕获Name \s* # 匹配空格 DataSetList[\s\=]*(?P<DataSetList>(?:'[\d\,]*'[\s\+]*)*) # 捕获DataSetList
当前输出结果
{'UID': '872', 'Name': 'banana', 'DataSetList': "'873,887,971,1055'\n "} {'UID': '437', 'Name': 'cherry', 'DataSetList': "'438,452,536,620,704,788,1143,1179,1563,1647,1731,1839,1875,1851,' +\n '1863,2060,2359,2443,2469,2620'\n "}
存在的问题
当前方案不够理想,因为命名捕获组DataSetList会同时捕获空格、换行和字面量+,后续还需要额外的后处理步骤。
改进方案
思路1:直接提取纯数字逗号组合
调整正则,跳过所有非目标字符(引号、加号、空格、换行),只捕获DataSetList对应的数字和逗号内容,利用非捕获组过滤无关结构:
ID[\s=]*(?P<UID>\d+)\s*Name[\s=]*'(?P<Name>[^']+)'\s*DataSetList[\s=]*(?:\s*'([\d,]+)'(?:\s*\+\s*'([\d,]+)')*)?
关键优化点:
- 用
\d+替代\d*,确保ID捕获到有效数字,避免空值 - 用
[^']+替代.*匹配Name,防止过度匹配到后续引号 - 拆分DataSetList的匹配逻辑,直接捕获每一段引号内的数字列表,忽略换行、空格和
+
处理方式:
对于单行格式,直接取第一个捕获组的内容;对于多行拼接格式,将多个捕获组的内容拼接即可得到完整列表。
思路2:单个命名捕获组+轻量后处理
如果希望用单个命名捕获组获取DataSetList,可开启DOTALL模式(让.匹配换行),再通过简单替换清理无关字符:
ID[\s=]*(?P<UID>\d+)\s*Name[\s=]*'(?P<Name>[^']+)'\s*DataSetList[\s=]*(?P<DataSetList>(?:\s*'[\d,]+'(?:\s*\+\s*'[\d,]+')*)?)
清理代码(以Python为例):
cleaned_dataset = re.sub(r"[^0-9,]", "", match.group('DataSetList'))
这种方式无需修改正则结构,仅通过一行替换就能得到纯数字逗号组合的字符串。
思路3:分阶段匹配(更稳健)
先匹配完整的item块,再在块内单独提取字段,避免跨块匹配风险:
- 匹配item块(需开启DOTALL模式):
item\s*(.*?)\s*end
- 在块内提取字段:
- 提取ID:
ID[\s=]*(\d+) - 提取Name:
Name[\s=]*'([^']+)' - 提取DataSetList:
DataSetList[\s=]*(?:\s*'([\d,]+)'(?:\s*\+\s*'([\d,]+)')*)?
- 提取ID:
这种方式逻辑更清晰,后续修改字段匹配规则也更灵活。
内容的提问来源于stack exchange,提问作者art8080
相关产品推荐
相关产品推荐

