带有可选捕获组和否定前瞻的正则表达式
regex with optional capturing groups and negative lookahead
这个问题困扰我有一段时间了。这是我要搜索的字符串的基础:
aa.bb.cc
每个标记(由“.”标记)可以是 succeeded/followed 具有零个或多个数组索引组:
例如aa[1].bb[2][3].cc
如果我的文本包含一个字符串,其中包含带有可选数组索引的确切标记数,我想匹配。但是,如果我要搜索的文本包含一个额外的“。”和令牌,我不想要任何匹配项:
例如aa[1].bb[2].cc.dd
我无法找到一个模式,其中包含具有负前瞻性的可选数组索引组 - 我一直在使用 (?!\.)
- 作为模式的最后一部分。这是我尝试过的模式之一:
((\w+)([\[\]\w]+)*\.(\w+)([\[\]\w]+)*\.(\w+)([\[\]\w]+)*)(?!\.)
如果我的搜索字符串是 aa[1].bb[2][3].cc
组如下:
- aa[1].bb[2][3].cc
- aa
- [1]
- bb
- [2][3]
- cc
- None
但是,如果我的搜索字符串包含一个标记,或者甚至只是“.”,如上所述,我希望整个匹配失败。但是,搜索 returns 相同的匹配组。
将字符串开头锚点 ^
添加到正则表达式的开头,将字符串结尾锚点 $
添加到正则表达式的末尾将导致它只匹配包含确切内容的字符串你只是描述而已。
>>> 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')
[]
您可以将 ((\w+)(\[\d+\])*\.)
的重复次数限制为 2,然后在正则表达式的尾部添加 (\w+)(\[\d+\])*
。并且不要忘记使用开始结束锚点。
^((\w+)(\[\d+\])*\.){2}(\w+)(\[\d+\])*$
显示正则表达式 here
我得到了想要的匹配。
使用否定的前瞻和后视。
(?<!\.)\w{2}(\[\d+])*\.\w{2}(\[\d+])*\.\w{2}(\[\d+])*(?!\.\w+)
使用这个模式,它会在任何地方捕获 3 组:
(?<!\.)\b((?:(?:\w+(?:\[\d+\])*)\.){2}(?:\w+(?:\[\d+\])*))(?![\w\.])
这个问题困扰我有一段时间了。这是我要搜索的字符串的基础:
aa.bb.cc
每个标记(由“.”标记)可以是 succeeded/followed 具有零个或多个数组索引组:
例如aa[1].bb[2][3].cc
如果我的文本包含一个字符串,其中包含带有可选数组索引的确切标记数,我想匹配。但是,如果我要搜索的文本包含一个额外的“。”和令牌,我不想要任何匹配项:
例如aa[1].bb[2].cc.dd
我无法找到一个模式,其中包含具有负前瞻性的可选数组索引组 - 我一直在使用 (?!\.)
- 作为模式的最后一部分。这是我尝试过的模式之一:
((\w+)([\[\]\w]+)*\.(\w+)([\[\]\w]+)*\.(\w+)([\[\]\w]+)*)(?!\.)
如果我的搜索字符串是 aa[1].bb[2][3].cc
组如下:
- aa[1].bb[2][3].cc
- aa
- [1]
- bb
- [2][3]
- cc
- None
但是,如果我的搜索字符串包含一个标记,或者甚至只是“.”,如上所述,我希望整个匹配失败。但是,搜索 returns 相同的匹配组。
将字符串开头锚点 ^
添加到正则表达式的开头,将字符串结尾锚点 $
添加到正则表达式的末尾将导致它只匹配包含确切内容的字符串你只是描述而已。
>>> 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')
[]
您可以将 ((\w+)(\[\d+\])*\.)
的重复次数限制为 2,然后在正则表达式的尾部添加 (\w+)(\[\d+\])*
。并且不要忘记使用开始结束锚点。
^((\w+)(\[\d+\])*\.){2}(\w+)(\[\d+\])*$
显示正则表达式 here 我得到了想要的匹配。
使用否定的前瞻和后视。
(?<!\.)\w{2}(\[\d+])*\.\w{2}(\[\d+])*\.\w{2}(\[\d+])*(?!\.\w+)
使用这个模式,它会在任何地方捕获 3 组:
(?<!\.)\b((?:(?:\w+(?:\[\d+\])*)\.){2}(?:\w+(?:\[\d+\])*))(?![\w\.])