首页 > 解决方案 > 正则表达式仅在某些字符内时匹配组

问题描述

我有这个{=\((COMMENT|TYPE)\):(.\X+?)}匹配某些字符串的正则表达式,但我只希望它在它找到的字符串在某个字符串内时进行匹配。因此,例如,我有这个https://i.imgur.com/TgPr407.png输入,它可以做我想要的,但我只希望它在它们之间{=(SETTINGS):和结尾之间匹配它们,}所以它不应该不匹配此屏幕截图中红色下划线的部分https://i.imgur.com/14X2rPX.png

标签: regex

解决方案


我将采用的方法是使用两个正则表达式,不需要特殊功能,并且应该适用于大多数语言。第一个正则表达式提取开头{=(SETTINGS):和结尾之间的内容}。只有当我们假设在这些字符的开始和结束序列之间,我们可以依赖{and}像它们一样出现,即仅单独嵌套在其中时,这才有可能。那么这些开闭序列之间的内容是0个或多个序列:

  1. 1 个或多个字符,而不是{or}
  2. A{后跟 0 个或多个{字符}}

一旦提取了内容,第二个正则表达式就可以完成剩下的工作。以下是用 Python 编码的(您没有指定语言,所以我可以自由选择)。我(?x)在正则表达式的开头指定。这将打开详细模式,允许忽略空格,允许我的正则表达式跨越多行并具有注释以便自我注释。

下次请不要使用图片。而是将实际文本复制并粘贴到您的问题中,以便我可以轻松创建输入字符串。因此,我使用了我自己的较短的输入。

第一个正则表达式:

{=\(SETTINGS\):((?:[^{}]+|(?:{[^{}}]*}))*)}

第一个正则表达式演示

第二个正则表达式:

{=\((?:COMMENT|TYPE)\):[^}]*}

第二个正则表达式演示

import re

s = """{=(SETTINGS):
{=(prefix):!}
{=(COMMENT):This is a comment}
{=(prefix):!}
{=(TYPE):number}
{=(prefix):!}
}
{=(COMMENT):This is to be ignored}
"""

pattern = r'''(?x)
{=\(SETTINGS\):       # {=(SETTINGS):
(                     # start of capture group 1
  (?:                 # start of non-capturing group
      [^{}]+          # one or more non {} characters
    |                 # or
      (?:{[^{}}]*})   # balanced {} expression
  )                   # end of non capturing group
  *                   # 0 or more times
)                     # end of capture group 1
}                     # }
'''

m = re.search(pattern, s)
if m:
    s2 = m[1]
    pattern2 = r'''(?x)
{=\((?:COMMENT|TYPE)\):  # {=(COMMENT): or {=(TYPE):
[^}]*                    # 0 or more non-} characters
}                        # }
'''
    matches = re.findall(pattern2, s2)
    print(matches)

印刷:

['{=(COMMENT):This is a comment}', '{=(TYPE):number}']

推荐阅读