8

任务:
- 给定:图像文件名列表
- 待办事项:使用不包含单词“thumb”的文件名创建一个新列表 - 即仅针对非缩略图图像(使用 PIL - Python Imaging Library)。

我试过r".*(?!thumb).*"但失败了。

我找到了解决方案(在stackoverflow上)将 a^添加到正则表达式并将其.*放入负前瞻中:r"^(?!.*thumb).*"这现在有效。

问题是,我想了解为什么我的第一个解决方案不起作用但我没有。由于正则表达式足够复杂,我真的很想了解它们。

我所理解的是,它^告诉解析器以下条件将在字符串的开头匹配。但是.*(不工作的)第一个示例中的不是也从字符串的开头开始吗?我认为它会从字符串的开头开始,并在到达“拇指”之前搜索尽可能多的字符。如果是这样,它将返回不匹配。

有人可以解释为什么r".*(?!thumb).*"不起作用,但r"^(?!.*thumb).*"可以吗?

谢谢!

4

3 回答 3

6

有人可以解释为什么r".*(?!thumb).*"不起作用,但 r"^(?!.*thumb).*"可以吗?

第一个将始终匹配,因为.*它将消耗所有字符串(因此它后面不能有任何东西以使负前瞻失败)。第二个有点复杂,将从行首开始匹配,直到遇到 'thumb' 为止的字符数量最多,如果存在,则整个匹配失败,因为该行确实以某些内容开头,然后是 'thumb' .

第二个更容易写成:

  • 'thumb' not in string
  • not re.search('thumb', string)(而不是匹配)

同样正如我在评论中提到的,您的问题是:

不包含单词“thumb”的文件名

所以你不妨考虑一下是否thumbs up应该排除在外。

于 2012-12-14T03:25:26.090 回答
3

(该死,乔恩打败了我。哦,好吧,无论如何你可以看看例子)

就像其他人所说的那样,正则表达式不是这项工作的最佳工具。如果您正在使用文件路径,请查看os.path

至于过滤您不想要的文件,您可以if 'thumb' not in filename: ...在剖析路径后执行(其中filenamea 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'
于 2012-12-14T03:44:42.607 回答
1

忽略有关正则表达式的所有内容,您的任务似乎相对简单:

  • 给定:图像文件名列表
  • 待办事项:使用不包含单词“thumb”的文件名创建一个新列表 - 即仅针对非缩略图图像(使用 PIL - Python Imaging Library)。

假设您有一个看起来像这样的文件名列表:

filenames = [ 'file1.jpg', 'file1-thumb.jpg', 'file2.jpg', 'file2-thumb.jpg' ]

然后你可以得到一个包含单词 thumb 的文件列表,如下所示:

not_thumb_filenames = [ filename for filename in filenames if not 'thumb' in filename ]

这就是我们所说的列表推导,本质上是以下的简写:

not_thumb_filenames = []
for filename in filenames:
  if not 'thumb' in filename:
    not_thumb_filenames.append(filename)

对于这个简单的任务,正则表达式并不是真正必需的。

于 2012-12-14T03:07:44.463 回答