列表理解的正则表达式问题

Regex trouble with list comprehension

我正在 Windows 上的 Python 3.7.6 中工作,我正在尝试使用正则表达式将一个 foo.csv.gz 文件名列表转换为相应的 foo.csv 文件名。下面是一段代码。

zippedFileNames = [re.search('[^/]*\.gz', link).group(0) for link in linksList]

unzippedFileNames = [re.search('.*\.csv', name).group(0) for name in zippedFileNames]

在上面的代码中,zippedFileNames 是通过从下载链接列表中分离出 .gz 文件名而创建的列表。这条线按我的预期工作,并采用 zippedFileNames[0] returns 一个字符串。 zippedFileNames[0]的类型是strzippedFileNames的类型是list.

然而,代码在第二行抛出错误:

Exception has occurred: AttributeError
'NoneType' object has no attribute 'group'
  File "H:\foo\bar\foobar.py", line 133, in <listcomp>
    x = [re.search('.*\.csv', name).group(0) for name in zippedFileNames]
  File "H:\foo\bar\foobar.py", line 133, in <module>
    x = [re.search('.*\.csv', name).group(0) for name in zippedFileNames]

此代码昨天可以运行,但今天停止运行,我不确定我更改了什么来破坏它。我相信在我尝试修改第二行的 pattern 以使用模式 '[^0-9\_].*\.csv' 省略第一位数字和下划线(文件名都遵循模式 0000_foo_bar_foobar.csv.gz)后它坏了。但是,即使将模式恢复为遗漏前的旧模式也不能解决我的问题。

有什么我没看到的吗?

谢谢!

编辑:

感谢您的回答。

我通过打印所有列表项和使用 print(None in zippedFileNames) 检查了我的列表中是否有 None。后一个测试返回了 False,而前一个测试返回了我所期望的所有项目。我也没有在我的链接列表中找到 None

当我 运行 仅在 linksListlinksList[0] 的元素之一上使用正则表达式 re.search 时,我得到了正确的字符串输出。

还有其他我可以尝试的东西吗?

编辑 2:

我尝试在单独的调用中重新使用原始正则表达式模式 '[^/]*\.gz',但它成功了。然后我也尝试使用 '[^/]*\.csv\.gz' 模式,希望得到与前一个模式相同的结果,但这个模式也返回了一个错误。我怀疑这些错误与 \.csv.

有关

决议 我在 .csv 上进行匹配,但结果我也有一个 .report 文件,而那个文件会丢弃整个脚本。迭代匹配有助于隔离问题。为了解决正则表达式,我匹配了模式 '.*\[^.gz]' 以保留所有文件扩展名,而不仅仅是 .csv。非常感谢!!

re.search returns None if the string doesn't match . Your second regex seems wrong. I think it should be '.*\.csv. You can test it with regex101.

[编辑]:你的正则表达式是正确的,你可能有一个与 zippedFileName

中的正则表达式不匹配的文件

检查您正在使用的列表、zippedFileNames 或 linksList 中是否有 None 或空值。

您可以使用

import re
zippedFileNames=['0001_foo1.csv', 'def.bz', '0000_foo2.csv.gz']
unzippedFileNames = []
for name in zippedFileNames:
  m = re.match(r"\d+_(.*\.csv)", name)
  if m:
    unzippedFileNames.append(m.group(1))
print(unzippedFileNames)
# => ['foo1.csv', 'foo2.csv']

参见Python demo

此处,unzippedFileNames 被声明为一个空列表。然后,遍历 zippedFileNames,根据 \d+_(.*\.csv) 正则表达式检查每个名称(请注意,re.match 仅在字符串的开头搜索匹配项),如果有匹配项(if m:) 第 1 组内容附加到 unzippedFileNames 列表。