【问题标题】:Python regex parse file name with underscore separated fieldsPython 正则表达式用下划线分隔的字段解析文件名
【发布时间】:2022-12-09 05:35:41
【问题描述】:

我有以下参数化文件名的格式。

"{variable}_{domain}_{GCMsource}_{scenario}_{member}_{RCMsource}_{RCMversion}_{frequency}_{start}-{end}_{fid}.nc"

例如

"pr_EUR-11_CNRM-CERFACS-CNRM-CM5_rcp45_r1i1p1_CLMcom-CCLM4-8-17_v1_day_20060101-20101231.nc"

(请注意,{start}-{end} 是连字符分隔而不是下划线)

各个字段始终由下划线分隔,并包含可预测(但可变)的格式。在示例文件名中,我省略了最后的 {fid} 字段,因为我希望它是可选的。

我想在 python 中使用正则表达式来解析这样的文件名,以便给我一个 dict 或类似的格式字符串中字段名称的键以及解析文件名的相应值。例如

{
    "variable": "pr", 
    "domain", "EUR-11", 
    "GCMsource": "CNRM-CERFACS-CNRM-CM5", 
    "scenario": "rcp45", 
    "member": "r1i1p1", 
    "RCMsource": "CLMcom-CCLM4-8-17", 
    "RCMversion": "v1", 
    "frequency": "day", 
    "start": "20060101", 
    "end": "20101231".
    "fid": None
}

可以根据字段限制每个字段的正则表达式模式。例如

  • “域”始终为 3 个字母 - 2 个数字
  • “成员”始终是 rWiXpY,其中 W、X 和 Y 是数字。
  • “场景”始终包含字母“rcp”,后跟 2 个数字。
  • “开始”和“结束”始终为 8 位数字 (YYYYMMDD)

字段中永远不会有下划线,下划线仅用于分隔字段。

请注意,我使用 https://github.com/r1chardj0n3s/parse 取得了一些成功,但我认为它不够灵活,无法满足我的需求(尝试解析具有相似格式的其他相似文件名经常会相互混淆)。

如果答案可以解释一些允许我这样做的正则表达式原则,那就太好了。

【问题讨论】:

  • 您是否尝试过自己构建正则表达式? Here 是一个在线正则表达式测试器,可以帮助您学习正则表达式和构建表达式。

标签: python regex


【解决方案1】:

python 正则表达式文档:https://docs.python.org/3/howto/regex.html#regex-howto

python正则表达式中的命名组: https://docs.python.org/3/howto/regex.html#non-capturing-and-named-groups

import re

test_string = """pr_EUR-11_CNRM-CERFACS-CNRM-CM5_rcp45_r1i1p1_CLMcom-CCLM4-8-17_v1_day_20060101-20101231.nc"""
pattern = r"""                       
(?P<variable>w+)_                      
(?P<domain>[a-zA-Z]{3}-d{2})_          
(?P<GCMsource>([A-Z0-9]+[-]?)+)_        
(?P<scenario>rcpd{2})_
(?P<member>([rip]d)+)_
(?P<RCMsource>([a-zA-Z0-9]-?)+)_
(?P<RCMversion>[a-zA-Z0-9]+)_
(?P<frequency>[a-zA-Z-0-9]+)_
(?P<start>d{8})-
(?P<end>d{8})
_?
(?P<fid>[a-zA-Z0-9]+)?
.nc
"""

re_object = re.compile(pattern, re.VERBOSE)  # we use VERBOSE flag

search_result = re_object.match(test_string)
print(search_result.groupdict())
# result:
"""
{'variable': 'pr', 'domain': 'EUR-11', 'GCMsource': 'CNRM-CERFACS-CNRM-CM5', 'scenario': 'rcp45', 'member': 'r1i1p1', 'RCMsource': 'CLMcom-CCLM4-8-17', 'RCMversion': 'v1', 'frequency': 'day', 'start': '20060101', 'end': '20101231', 'fid': None}
"""

【讨论】:

  • 当我在 <fid> 的模式末尾添加 + 时效果很好(可以是多个字符)。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多