Python未提取预期模式

Python未提取预期模式,python,regex,match,Python,Regex,Match,我是RegEx新手,我正在尝试使用re.findall执行一个简单的匹配来提取项目列表。然而,我并没有得到预期的结果。你能解释一下为什么我还要根据下面的正则表达式模式得到这个字符串的第一部分,以及我需要修改什么才能得到想要的输出吗 import re string = '''aaaa_1y345_xyz_orange_bar_1 aaaa_123a5542_xyz_orange_bar_1 bbbb_1z34512_abc_purple_bar_1''' print(re.findall('_

我是RegEx新手,我正在尝试使用re.findall执行一个简单的匹配来提取项目列表。然而,我并没有得到预期的结果。你能解释一下为什么我还要根据下面的正则表达式模式得到这个字符串的第一部分,以及我需要修改什么才能得到想要的输出吗

import re
string = '''aaaa_1y345_xyz_orange_bar_1
aaaa_123a5542_xyz_orange_bar_1
bbbb_1z34512_abc_purple_bar_1'''

print(re.findall('_\w+_\w+_bar_\d+', string))
电流输出:

['_1y345_xyz_orange_bar_1', '_123a5542_xyz_orange_bar_1', '_1z34512_abc_purple_bar_1']
期望输出:

['_xyz_orange_bar_1', '_xyz_orange_bar_1', '_abc_purple_bar_1']

您的
\w
使用过于随意。它不仅能找到字母,还能找到数字和下划线。从:

未指定区域设置和UNICODE标志时,匹配任何字母数字字符和下划线;这相当于设置
[a-zA-Z0-9.]
。对于区域设置,它将匹配集合
[0-9.]
以及当前区域设置中定义为字母数字的任何字符。如果设置了UNICODE,这将匹配字符
[0-9.]
以及UNICODE字符属性数据库中分类为字母数字的任何字符

相反,我们需要实际的角色分组来匹配

_[a-z]+_[a-z]+_bar_[0-9]+
如果实际需要不带下划线的
\w
的完全匹配,可以将字符分组更改为:

 [a-zA-Z0-9]

代码的问题在于,
\w
模式相当于以下字符集:
[a-zA-Z0-9\]

我想您需要匹配相同的集合,但不带下划线:

import re
string = '''aaaa_1y345_xyz_orange_bar_1
aaaa_123a5542_xyz_orange_bar_1
bbbb_1z34512_abc_purple_bar_1'''

print(re.findall('_[a-zA-Z0-9]+_[a-zA-Z0-9]+_bar_\d+', string))
输出:

['_xyz_orange_bar_1', '_xyz_orange_bar_1', '_abc_purple_bar_1']

.[a-z]+\uw+\uu-bar\ud+
应该可以工作

import re
string = '''aaaa_1y345_xyz_orange_bar_1
aaaa_123a5542_xyz_orange_bar_1
bbbb_1z34512_abc_purple_bar_1'''
print(re.findall('_[a-z]+_\w+_bar_\d+', string))
o/p


\w
模式匹配字母、数字和
\u
符号。根据Python版本和使用的选项,它可以匹配的字母和数字可能来自整个Unicode范围,也可能只是ASCII

因此,解决此问题的最佳方法是将
\w
替换为
[^\w\uu]

import re
string = '''aaaa_1y345_xyz_orange_bar_1
aaaa_123a5542_xyz_orange_bar_1
bbbb_1z34512_abc_purple_bar_1'''
print(re.findall(r'_[^\W_]+_[^\W_]+_bar_[0-9]+', string))
# => ['_xyz_orange_bar_1', '_xyz_orange_bar_1', '_abc_purple_bar_1']

详细信息

  • -下划线
  • [^\W_]+
    -1个或多个数字或字母字符(a
    [^
    启动求反字符类,
    \W
    匹配任何非单词字符,
    \u
    添加以匹配除
    \u
    以外的任何单词字符)
  • \u[^\ W\u]+
    -同上
  • \u bar
    -文字子字符串
    \u bar
  • [0-9]+
    -1个或更多ASCII数字

请参阅。

您的问题在于正则表达式贪婪,并试图尽可能多地匹配。有时,可以通过在
+
(加号)后添加
(问号)来解决此问题。但是,在您当前的解决方案中,这是不可行的(至少以任何简单的方式-可能通过一些前瞻性操作完成)。但是,您可以选择另一种模式,该模式明确禁止匹配
(下划线)字符,如下所示:

import re
string = '''aaaa_1y345_xyz_orange_bar_1
aaaa_123a5542_xyz_orange_bar_1
bbbb_1z34512_abc_purple_bar_1'''

print(re.findall('_[^_\W]+_[^_\W]+_bar_\d+', string))

这将符合您的期望。
[^…]
construct的意思是不,因此不加下划线,也不加空格。

string
?从什么时候开始?
string
是标准库模块的名称,但可以安全地用作变量名。无论如何,最好按照它们是什么而不是它们的类型来命名,以避免任何可能的冲突。感谢您的详细解释N
import re
string = '''aaaa_1y345_xyz_orange_bar_1
aaaa_123a5542_xyz_orange_bar_1
bbbb_1z34512_abc_purple_bar_1'''

print(re.findall('_[^_\W]+_[^_\W]+_bar_\d+', string))