簡體   English   中英

python中的正則表達式:匹配可選子字符串的重復項

[英]Regex in python: matching duplicates of optional substrings

我正在開發一個python軟件包,除其他事項外,該軟件包需要處理包含數據集名稱列表的文件,並且需要提取這些名稱的組成部分。

數據集名稱的示例為:

  • diskLineLuminosity:halpha:rest:z1.0
  • diskLineLuminosity:halpha:rest:z1.0:dust
  • diskLineLuminosity:halpha:rest:z1.0:contam_NII
  • diskLineLuminosity:halpha:rest:z1.0:contam_NII:contam_OII:contam_OIII
  • diskLineLuminosity:halpha:rest:z1.0:contam_NII:contam_OIII:灰塵
  • diskLineLuminosity:halpha:rest:z1.0:contam_OII:contam_NII
  • diskLineLuminosity:halpha:rest:z1.0:contam_NII:recent

我正在尋找一種使用正則表達式解析數據集名稱的方法,以提取所有數據集信息,包括“ 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使用正則表達式,因此如何修改re.search字符串以成功解析上述所有數據集名稱並提取子字符串中的信息(包括所有污染實例的列表)?

感謝您的任何幫助,您可以提供!

如果您仍在學習正則表達式 (老實說,以后也要這樣做),請養成盡可能多使用verbose模式的習慣,這樣可以使代碼更好,可讀性更高。

也就是說,您可以使用

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

只是稍微改變了順序,並在其contam部分使用了一個非捕獲組,請參閱regex101.com上的演示

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM