【问题标题】:Multiple captures within a string字符串中的多个捕获
【发布时间】:2021-08-04 05:36:12
【问题描述】:

尚未找到完全回答这种情况的关于 SO 的 Q/A。我已经实施了一些解决方案,以达到我所拥有的程度。

我正在解析VCF files 的标头(元数据)部分。每一行的格式为:

##TAG=<key=val,key=val,...>

我有一个正则表达式可以解析 <> 中的多个 k-v 对,但我似乎无法添加 <> 并让它仍然“工作”。

s = 'a=1,b=two,c="three"'

pat = re.compile(r'''(?P<key>\w+)=(?P<value>[^,]*),?''')
match = pat.findall(s)
print(dict(match))
#{'a': '1', 'b': 'two', 'c': '"three"'}

还有,

s = 'a=1,b=two,c="three"'

pat = re.compile(r'''(?:(?P<key>\w+)=(?P<value>[^,]*),?)''')
match = pat.findall(s)
print(match)
print(dict(match))
#[('a', '1'), ('b', 'two'), ('c', '"three"')]
#{'a': '1', 'b': 'two', 'c': '"three"'}

所以,我想我可以做到:

s = '<a=1,b=two,c="three">'

pat = re.compile(r'''<(?:(?P<key>\w+)=(?P<value>[^,]*),?)>''')
match = pat.findall(s)
print(match)
print(dict(match))
#[]
#{}

如果可能的话,我真的很想做这样的事情:

\#\#(?P&lt;tag&gt;)=&lt;(?:(?P&lt;key&gt;\w+)=(?P&lt;value&gt;[^,]*),?)&gt;

并捕获 TAG 和所有 k-v 对。显然,我希望它“工作”。

我意识到这里的“正确”解决方案可能使用解析器而不是正则表达式。但我是一个生物信息学的人,而不是一个程序员。并且格式非常一致,并以(几乎)始终遵循的标准化规范进行布局。

【问题讨论】:

    标签: python regex regex-group capture-group


    【解决方案1】:

    PyPi regex:

    import regex
    s = '##TAG=<key=val,key2=val2>'
    pat = regex.compile(r'''##(?P<tag>\w+)=<(?:(?P<key>\w+)=(?P<value>[^,<>]*),?)*>''')
    match = pat.search(s)
    print([match.group("tag"), list(zip(match.captures("key"), match.captures("value")))])
    

    Python proof | Regex explanation

    --------------------------------------------------------------------------------
      ##                       '##'
    --------------------------------------------------------------------------------
      (?P<tag>                  group and capture to \k<tag>:
    --------------------------------------------------------------------------------
        \w+                      word characters (a-z, A-Z, 0-9, _) (1 or
                                 more times (matching the most amount
                                 possible))
    --------------------------------------------------------------------------------
      )                        end of \k<tag>
    --------------------------------------------------------------------------------
      =<                       '=<'
    --------------------------------------------------------------------------------
      (?:                      group, but do not capture (0 or more times
                               (matching the most amount possible)):
    --------------------------------------------------------------------------------
        (?P<key>                        group and capture to \k<key>:
    --------------------------------------------------------------------------------
          \w+                      word characters (a-z, A-Z, 0-9, _) (1
                                   or more times (matching the most
                                   amount possible))
    --------------------------------------------------------------------------------
        )                        end of \k<key>
    --------------------------------------------------------------------------------
        =                        '='
    --------------------------------------------------------------------------------
        (?P<value>                 group and capture to \k<value>:
    --------------------------------------------------------------------------------
          [^,<>]*                  any character except: ',', '<', '>' (0
                                   or more times (matching the most
                                   amount possible))
    --------------------------------------------------------------------------------
        )                        end of \k<value>
    --------------------------------------------------------------------------------
        ,?                       ',' (optional (matching the most amount
                                 possible))
    --------------------------------------------------------------------------------
      )*                       end of grouping
    --------------------------------------------------------------------------------
      >                        '>'
    

    结果['TAG', [('key', 'val'), ('key2', 'val2')]]

    【讨论】:

    • 盖克!我几乎可以发誓我尝试了那么长的路。干得好!
    • 第二个想法,我没有。我没有尝试过search 方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-15
    • 1970-01-01
    相关资源
    最近更新 更多