具有可选捕获组和负向前瞻的正则表达式

时间:2016-06-23 19:12:50

标签: python regex negative-lookahead

这个问题已经存在了很长一段时间。这是我想要搜索的字符串的基础:

aa.bb.cc

每个令牌(由'。'标记)可以成功/跟随零个或多个数组索引组:

e.g。 aa[1].bb[2][3].cc

如果我的文本包含一个字符串,其中包含具有可选数组索引的标记的确切数量,我想匹配。但是,如果我要搜索的文字包含额外的'。'和令牌,我不想要任何匹配:

例如aa[1].bb[2].cc.dd

我很难找到一个模式,其中包含带有负前瞻的可选数组索引组 - 我一直在使用(?!\.) - 作为模式的最后一部分。这是我尝试过的模式之一:

((\w+)([\[\]\w]+)*\.(\w+)([\[\]\w]+)*\.(\w+)([\[\]\w]+)*)(?!\.)

如果我的搜索字符串为aa[1].bb[2][3].cc,则组如下:

  1. AA [1]的.bb [2] [3] .CC
  2. AA
  3. [1]
  4. BB
  5. [2] [3]
  6. CC
  7. 但是,如果我的搜索字符串包含一个或多个令牌,或者甚至只是'。',如上所述,我希望整个匹配失败。但是,搜索会返回相同的匹配组。

4 个答案:

答案 0 :(得分:1)

使用此模式,它将在任何地方捕获3组:

(?<!\.)\b((?:(?:\w+(?:\[\d+\])*)\.){2}(?:\w+(?:\[\d+\])*))(?![\w\.])

Demo

答案 1 :(得分:0)

将起始字符串锚^添加到开头,将字符串结尾$添加到正则表达式的末尾将使其仅匹配包含您所描述内容的字符串仅此而已。

>>> regex = re.compile('^((\w+)([\[\]\w]+)*\.(\w+)([\[\]\w]+)*\.(\w+)([\[\]\w]+)*)$')
>>> regex.findall('aa[1].bb[2][3].cc')
[('aa[1].bb[2][3].cc', 'aa', '[1]', 'bb', '[2][3]', 'cc', '')]
>>> regex.findall('aa[1].bb[2][3].cc.dd')
[]

答案 2 :(得分:0)

您可以将((\w+)(\[\d+\])*\.)的重复次数加2,然后在正则表达式的尾随处添加(\w+)(\[\d+\])*。并且不要忘记使用起始锚点。

^((\w+)(\[\d+\])*\.){2}(\w+)(\[\d+\])*$

请参阅演示:https://regex101.com/r/jG3uK7/7

答案 3 :(得分:0)

显示正则表达式here 我得到了理想的匹配。

使用负向前瞻和后视。

(?<!\.)\w{2}(\[\d+])*\.\w{2}(\[\d+])*\.\w{2}(\[\d+])*(?!\.\w+)