就是这样:我在Ubuntu Linux下在家编写了一段Python代码,一个简单的日志文件解析器。该代码运行完美。
现在,我重新开始工作,这里有一台Windows 10计算机,上面已经安装了MSYS2,并且使用了它的Python(2和3)。现在,当我在相同的文件上运行相同的代码时,我得到:
AttributeError: 'NoneType' object has no attribute 'group'
...当代码遇到时,例如说
m.group(1)
,这实际上意味着变量m
为None。这是一个测试脚本
test.py
,它设置相同的行和相同的正则表达式-不幸的是,它不会重现该错误:#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys,os
import re
line = """TEST001 sample 1/00001: X: 1 Y: 1 Z: 1 TEMPC: 25.95°C
"""
m = re.search(r"""X: (\d+?) Y: (\d+?) Z: (\d+?) TEMPC: ([\d.]+?)°C""", line)
print(line, m, type(line))
请注意,以上所有行尾均为
\n
(即纯LF)如果现在使用MSYS2中的Python运行此代码-MSYS2默认值(在
/usr/bin/python{2,3}
,即C:\msys64\usr\bin\python{2,3}.exe
;或者在MINGW64 shell中的Python 3,在/mingw64/bin/python3
中(即,):user@PC MSYS /tmp
$ python2 test.py
('TEST001 sample 1/00001: X: 1 Y: 1 Z: 1 TEMPC: 25.95\xc2\xb0C\n', <_sre.SRE_Match object at 0x6ffffffcca8>, <type 'str'>)
user@PC MSYS /tmp
$ python3 test.py
TEST001 sample 1/00001: X: 1 Y: 1 Z: 1 TEMPC: 25.95°C
<re.Match object; span=(28, 57), match='X: 1 Y: 1 Z: 1 TEMPC: 25.95°C'> <class 'str'>
user@PC MSYS /tmp
$ /mingw64/bin/python3 test.py
TEST001 sample 1/00001: X: 1 Y: 1 Z: 1 TEMPC: 25.95�C
<re.Match object; span=(28, 57), match='X: 1 Y: 1 Z: 1 TEMPC: 25.95�C'> <class 'str'>
注意这里,MSYS2 Python2不能真正打印度数的UTF-8字符(这是预期的); MSYS2 Python3可以打印此字符-但MINGW64 Python3再次无法打印此字符,尽管应该吗?
无论如何-由于我的实际工作脚本需要使用
C:\msys64\mingw64\bin\python3.exe
和/mingw64/bin/python3
,因此我在MSYS2或MINGW64外壳中明确运行我的实际工作脚本,因为我的实际工作脚本需要使用matplotlib
和numpy
,并且这些脚本只能安装在MINGW64外壳上...但是,正如我提到的那样,由于m = re.search(...)
的结果是m
变为None,所以程序实际上崩溃了。编辑:我在我实际的工作脚本中的代码是:
with open(file_abspath, 'rt') as thelogfile:
for line in thelogfile:
if "something" in line: ...
elif line.startswith("TEST001 sample"):
m = re.search(r"""X: (\d+?) Y: (\d+?) Z: (\d+?) TEMPC: ([\d.]+?)°C""", line)
print(line, m, type(line)) # added for debug
....
...并打印出来:
TEST001 sample 1/00001: X: 1 Y: 1 Z: 1 TEMPC: 25.95°C
None <class 'str'>
...这就是我在以上示例中使用的内容。
我的实际工作脚本和带有数据行的文件都具有Unix行结尾(
\n
,即LF),并且我尝试通过在test.py
上面进行模拟,也将其与普通的Unix行一起使用结局。任何人都不会知道,为什么我的实际工作脚本在解析完全相同的行时会逐行读取文件(即
re.search
的结果为None)失败,所以传递的更少而没有问题。 test.py
,如上面的摘要所示? 最佳答案
我推测输入文件中的一行或多行(而不是上面测试的行)不符合您期望的模式。这是一个建议的脚本,您可以尝试清除不匹配的行:
filepath = 'your_input.csv'
with open(filepath) as fp:
line = fp.readline()
cnt = 1
while line:
m = re.search(r"""X: (\d+?) Y: (\d+?) Z: (\d+?) TEMPC: ([\d.]+?)°C""", line)
if not m:
print("Line #" + str(cnt) + " has a problem: " + line)
line = fp.readline()
cnt += 1
假设只有几行令人反感的话,您也许可以手动编辑文件并修复数据。