You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

优化正则表达式,精准捕获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块,再在块内单独提取字段,避免跨块匹配风险:

  1. 匹配item块(需开启DOTALL模式):
item\s*(.*?)\s*end
  1. 在块内提取字段:
    • 提取ID:ID[\s=]*(\d+)
    • 提取Name:Name[\s=]*'([^']+)'
    • 提取DataSetList:DataSetList[\s=]*(?:\s*'([\d,]+)'(?:\s*\+\s*'([\d,]+)')*)?

这种方式逻辑更清晰,后续修改字段匹配规则也更灵活。


内容的提问来源于stack exchange,提问作者art8080

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 04:20:22