python中的正则表达式:匹配可选子串的重复

时间:2018-02-07 20:49:25

标签: python regex syntax duplicates repeat

我正在开发一个python包,除其他外,需要处理包含数据集名称列表的文件,我需要提取这些名称的组件。

数据集名称的示例如下:

  • diskLineLuminosity:halpha:其余:Z1.0
  • diskLineLuminosity:halpha:其余:Z1.0:灰尘
  • diskLineLuminosity:halpha:其余:Z1.0:contam_NII
  • diskLineLuminosity:halpha:其余:Z1.0:contam_NII:contam_OII:contam_OIII
  • diskLineLuminosity:halpha:其余:Z1.0:contam_NII:contam_OIII:灰尘
  • diskLineLuminosity:halpha:其余:Z1.0:contam_OII:contam_NII
  • diskLineLuminosity:halpha:其余:Z1.0:contam_NII:最近

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

作为一个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

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

感谢您提供的任何帮助!

2 个答案:

答案 0 :(得分:2)

如果您仍然学习正则表达式(说实话,以后也是如此),养成尽可能经常使用verbose模式的习惯,这样可以获得更好的代码和更易读的表达。

那就是说,你可以用

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

稍微更改了一下订单,并在contam部分内部使用了非捕获组,请参阅a demo on regex101.com

答案 1 :(得分:0)

您可以使用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']

输出:

{{1}}