任务:
- 给定:图像列表文件名
- todo:创建一个文件名不包含单词“thumb”的新列表 - 即仅定位非缩略图图像(使用PIL - Python Imaging Library)。
我已经尝试r".*(?!thumb).*"
,但失败了。
我找到了解决方案(此处在stackoverflow上),将^
添加到正则表达式,并将.*
置于否定前瞻:r"^(?!.*thumb).*"
,现在可以正常工作。< / p>
问题是,我想了解为什么我的第一个解决方案不起作用,但我不这样做。 由于正则表达式足够复杂,我真的很想理解它们。
我理解的是^
告诉解析器在字符串的开头要满足以下条件。但是,(不工作)第一个例子中的.*
也不是从字符串的开头开始的吗?
我认为它会从字符串的开头开始,并在到达“拇指”之前搜索尽可能多的字符。如果是这样,它将返回不匹配。
有人可以解释为什么r".*(?!thumb).*"
不起作用,r"^(?!.*thumb).*"
却有效吗?
谢谢!
答案 0 :(得分:5)
有人可以解释为什么
r".*(?!thumb).*"
不起作用r"^(?!.*thumb).*"
呢?
第一个将始终匹配,因为.*
将消耗所有字符串(因此不能为负向前瞻失败的任何事物后跟)。第二个是有点复杂的,并且将从行的开头匹配,最多的字符直到它遇到“拇指”并且如果存在,那么整个匹配失败,因为该行开始后面跟着'拇指'
第二个更容易写成:
'thumb' not in string
not re.search('thumb', string)
(而不是匹配)正如我在评论中提到的,你的问题是:
文件名不包含 字 “拇指”
因此,您可能希望考虑是否应该排除thumbs up
。
答案 1 :(得分:2)
(Darn,Jon打败了我。好吧,你可以看看这些例子)
就像其他人说的那样,正则表达式并不是这项工作的最佳工具。如果您正在使用文件路径,请查看os.path。
对于您不想要的过滤文件,一旦解剖了路径(if 'thumb' not in filename: ...
为filename
),您就可以str
。
对于后代,这是我对那些正则表达式的看法。 r".*(?!thumb).*"
不起作用,因为.*
是贪婪的,前瞻的优先级非常低。看看这个:
>>> re.search('(.*)((?!thumb))(.*)', '/tmp/somewhere/thumb').groups()
('/tmp/somewhere/thumb', '', '')
>>> re.search('(.*?)((?!thumb))(.*)', '/tmp/somewhere/thumb').groups()
('', '', '/tmp/somewhere/thumb')
>>> re.search('(.*?)((?!thumb))(.*?)', '/tmp/somewhere/thumb').groups()
('', '', '')
最后一个很奇怪......
另一个正则表达式(r"^(?!.*thumb).*"
)有效,因为.*
位于前瞻内部,因此您不会遇到任何字符被盗的问题。您实际上甚至不需要^
,具体取决于您使用的是re.match
还是re.search
:
>>> re.search('((?!.*thumb))(.*)', '/tmp/somewhere/thumb').groups()
('', 'humb')
>>> re.search('^((?!.*thumb))(.*)', '/tmp/somewhere/thumb').groups()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'groups'
>>> re.match('((?!.*thumb))(.*)', '/tmp/somewhere/thumb').groups()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'groups'
答案 2 :(得分:0)
忽略关于正则表达式的所有内容,您的任务似乎相对简单:
- 给出:图像文件名列表
- todo:创建一个新的列表,其文件名不包含单词“thumb” - 即仅定位非缩略图图像(使用PIL - Python 影像库)。
假设您有一个类似于以下内容的文件名列表:
filenames = [ 'file1.jpg', 'file1-thumb.jpg', 'file2.jpg', 'file2-thumb.jpg' ]
然后你可以得到一个包含单词thumb的 not 的文件列表,如下所示:
not_thumb_filenames = [ filename for filename in filenames if not 'thumb' in filename ]
这就是我们所说的list comprehension,基本上是简写:
not_thumb_filenames = []
for filename in filenames:
if not 'thumb' in filename:
not_thumb_filenames.append(filename)
这个简单的任务不一定需要正则表达式。