python中的Regex:匹配可选子字符串的副本

2024-04-26 03:52:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在开发一个python包,它需要处理一个包含数据集名称列表的文件,并且需要提取这些名称的组件

数据集名称示例如下:

  • 磁盘线uminosity:halpha:rest:z1.0 你知道吗
  • 磁盘线uminosity:halpha:rest:z1.0:灰尘
  • 磁盘线uminosity:halpha:rest:z1.0:续
  • 磁盘线uminosity:halpha:rest:z1.0继续:继续
  • 磁盘线uminosity:halpha:rest:z1.0:contam\u NII:contam\u OIII:灰尘
  • 磁盘线uminosity:halpha:rest:z1.0:contam\u OII:继续
  • 磁盘线uminosity:halpha:rest:z1.0:续:最近

我正在寻找一种使用regex解析数据集名称的方法,以提取所有数据集信息,包括“contam_u3;*”的所有实例的列表(其中允许零个实例)。我意识到我可以拆分字符串并使用fnmatch.filter或等效的方法,但是我还需要能够标记与上述语法不匹配的错误数据集名称。另外,regex目前在整个包中广泛用于类似的情况,因此我不想引入第二种解析方法

作为一名MWE,通过一个示例数据集名称,我拼凑了:

import re
datasetName = "diskLineLuminosity:halpha:rest:z1.0:contam_NII:recent"
M = re.search("^(disk|spheroid)LineLuminosity:([^:]+):([^:]+):z([\d\.]+)(:recent)?(:contam_[^:]+)?(:dust[^:]+)?",datasetName)

这将返回:

print M.group(1,2,3,4,5,6,7)
('disk', 'halpha', 'rest', '1.0', None, ':contam_NII', None)

在包中,此正则表达式搜索需要进入一个类似于以下内容的函数:

def getDatasetNameInformation(datasetName):
    INFO = re.search("^(disk|spheroid)LineLuminosity:([^:]+):([^:]+):z([\d\.]+)(:recent)?(:contam_[^:]+)?(:dust[^:]+)?",datasetName)
    if not INFO:
        raise ParseError("Cannot parse '"+datasetName+"'!")
    return INFO

我对使用regex还是个新手,那么如何修改re.search字符串来成功解析上述所有数据集名称并提取子字符串中的信息(包括所有污染实例的列表)

谢谢你的帮助


Tags: 数据实例方法字符串re名称rest列表
2条回答

您可以使用((?::contam_[^:]+)*)捕获所有这些contam_:这将在一个组中捕获所有这些contam_。然后启动第二个正则表达式,仅对该匹配应用它,并将该结果用作第一个结果中的嵌套列表:

import re
datasetName = "diskLineLuminosity:halpha:rest:z1.0:recent:contam_NII:contam_NII:dust"
M = re.search("^(disk|spheroid)LineLuminosity:([^:]+):([^:]+):z([\d\.]+)(?::(recent))?((?::contam_[^:]+)*)(?::(dust))?",datasetName)
lst = list(M.groups())
if lst[5]:
    lst[5] = re.findall(":contam_([^:]+)", lst[5])

print(lst)

输出:

['disk', 'halpha', 'rest', '1.0', 'recent', ['NII', 'NII'], 'dust']

如果您仍在学习正则表达式(老实说,以后也一样),那么请养成尽可能多地使用verbose模式的习惯,这样可以生成更好的代码和更可读的表达式

也就是说,你可以

^
(disk|spheroid)
LineLuminosity:
([^:]+):
([^:]+):
z([\d\.]+)
((?::contam_[^:]+)+)?
(:recent)?
(:dust[^:]*)?

只是稍微改变了顺序,在contam部分中使用了一个非捕获组,请参见a demo on regex101.com

相关问题 更多 >