列表理解的正则表达式问题
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]
的类型是str
,zippedFileNames
的类型是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
。
当我 运行 仅在 linksList
、linksList[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
列表。
我正在 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]
的类型是str
,zippedFileNames
的类型是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
。
当我 运行 仅在 linksList
、linksList[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
列表。