正则表达式命名组(如果存在)

regex named group if exist

早上好,

我有一个字符串,我需要解析和打印两个命名组的内容,知道其中一个可能不存在。

字符串看起来像这样(基本是/proc/pid/cmdline的内容):

"""
<some chars with letters / numbers / space / punctuation> /CLASS_NAME:myapp.server.starter.StarterHome /PARAM_XX:value_XX /PARAM_XX:value_XX /CONFIG_FILE:myapp.server.config.myconfig.txt /PARAM_XX:value_XX /PARAM_XX:value_XX /PARAM_XX:value_XX <some chars with letters / numbers / space / punctuation>
"""

我的进程具有几乎相同的模式,即:

/CLASS_NAME:myapp.server.starter.StarterHome 始终存在,但是 /CONFIG_FILE:myapp.server.config.myconfig.txt 并不总是存在。

我正在使用 python2 和 re 模块来捕获值。到目前为止,我的模式看起来像这样,我能够捕捉到我想要的对应于 /CLASS_NAME

的值
re.compile('CLASS_NAME:\w+\W\w+\W\w+\W(?P<class>\w+)')

因为 /CONFIG_FILE 是否存在,我在 myregexp 中添加了以下内容:

re.compile(r"""CLASS_NAME:\w+\W\w+\W\w+\W(?P<class>\w+).*?
               (CONFIG_FILE:\w+\W\w+\W\w+\W(?P<cnf>\w+.txt))?
            """, re.X)

我的理解是 rexexp 的第二部分是可选的,因为整个部分都在括号之间,然后是 ?

不幸的是我的假设是错误的,因为它无法捕捉到它

我也试过删除第一个 ? 但没有用。

我通过 PYTHEX 进行了几次尝试,试图理解我的正则表达式,但找不到解决方案。

谁能对解决我的案子有什么建议?

您可以将整个可选部分包装在一个可选的非捕获组中,并使 CONFIG_FILE 的捕获组成为必需的:

re.compile(r"""CLASS_NAME:(?:\w+\W+){3}(?P<class>\w+)(?:.*?
               (CONFIG_FILE:(?:\w+\W+){3}(?P<cnf>\w+\.txt)))?
        """, re.X)

如果有换行符,请使用 re.X | re.S 修饰符选项。注意 \w+\W\w+\W\w+\W 最好写成 (?:\w+\W+){3}.

regex demo

主要区别在于(?:.*?(CONFIG_FILE:(?:\w+\W+){3}(?P<cnf>\w+\.txt)))?部分:

  • (?: - 可选的开始(因为它后面有一个贪婪的 ? 量词)非捕获组匹配
    • .*? - 任何 0+ 个字符,尽可能少
    • (CONFIG_FILE:(?:\w+\W+){3}(?P<cnf>\w+\.txt)) - 匹配
      • CONFIG_FILE: - 文字子串
      • (?:\w+\W+){3} - 三个包含 1+ 个单词字符的序列,后跟 1+ 个非单词字符
      • (?P<cnf>\w+\.txt) - 组 cnf:1+ 个字符,一个点(注意它应该被转义)然后 txt
  • )? - 可选非捕获组结束(将尝试一次)