ОК, думаю, я понял это - давайте сначала проведем этот тест: сначала создадим текстовый файл, test.txt
, Unix (только LF) окончания строк:
TEST001 sample 1/00001: X: 1 Y: 1 Z: 1 TEMPC: 25.95°C
TEST002 sample 1/00002: X: 1 Y: 1 Z: 1 TEMPC: 25.95°C
TEST003 sample 1/00003: X: 1 Y: 1 Z: 1 TEMPC: 25.95°C
Затем давайте попробуемэтот скрипт, test2.py
:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys,os
import re
with open('test.txt', 'rt') as thelogfile:
for line in thelogfile:
if "something" in line: pass
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
Теперь, если я запусту этот скрипт в Python 3 оболочки MINGW64 (так, /mingw64/bin/python3
):
user@PC MINGW64 /tmp
$ python3 test2.py
TEST001 sample 1/00001: X: 1 Y: 1 Z: 1 TEMPC: 25.95°C
None <class 'str'>
Итак, сноваматч не удался. Теперь давайте попробуем отладить с помощью pdb
:
user@PC MINGW64 /tmp
$ python3 -m pdb test2.py
> c:/msys64/tmp/test2.py(4)<module>()
-> import sys,os
(Pdb) b 11
Breakpoint 1 at c:/msys64/tmp/test2.py:11
(Pdb) r
> c:/msys64/tmp/test2.py(11)<module>()
-> m = re.search(r"""X: (\d+?) Y: (\d+?) Z: (\d+?) TEMPC: ([\d.]+?)▒C""", line)
(Pdb) p line
'TEST001 sample 1/00001: X: 1 Y: 1 Z: 1 TEMPC: 25.95°C\n'
(Pdb) n
> c:/msys64/tmp/test2.py(12)<module>()
-> print(line, m, type(line)) # added for debug
(Pdb) p m
None
(Pdb)
Хорошо, так что здесь мы определенно можем видеть, что это та же строка текста, что и в OP, и объект соответствия (возвращаемый из re.search
)Нет, поэтому проблема по-прежнему присутствует.
Однако обратите внимание, что когда PDB выводит строку «m = re.search ...», знак степени поврежден:
▒C
... тогда как если я печатаю строку самостоятельно, знак градуса в порядке:
°C
Итак, подозревая, что это может иметь отношение к кодировкам, я попробовал это в pdb
- во-первых, я скопировал и вставил строку, которая выгружала pdb, со сломанным знаком степени:
(Pdb) re.search(r"""X: (\d+?) Y: (\d+?) Z: (\d+?) TEMPC: ([\d.]+?)▒C""", line)
(Pdb)
Очевидно, что в этом случае возврата нет. Затем я попытался запустить то же самое, за исключением того, что я скопировал и вставил строку re.search
непосредственно из исходного файла в терминал:
(Pdb) re.search(r"""X: (\d+?) Y: (\d+?) Z: (\d+?) TEMPC: ([\d.]+?)°C""", line)
<re.Match object; span=(28, 58), match='X: 1 Y: 1 Z: 1 TEMPC: 25.95°C'>
Хорошо, так что здесь мы получили совпадение!
Таким образом, даже если этот вид подразумевает, что кодировка файла кода source не совсем верна - я обнаружил http://python -notes.curiousefficiency.org / en / latest / python3/text_file_processing.html и увидел аргумент encoding
для open()
, поэтому попытался использовать его с файлом data , - и это единственное изменение, которое мне нужно было сделать свыше test2.py
:
with open('test.txt', 'rt', encoding='utf-8') as thelogfile:
... и, наконец, он начал работать:
user@PC MINGW64 /tmp
$ python3 test2.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'>
Почему это происходит, особенно для Python3 в оболочке MINGW64 (и почему он до сих порпроблема печати правильного UTF-8 в оболочку, где в противном случае Python3 оболочки MSYS2 не имеет проблем с этим), я не могу сказать - но, по крайней мере, я могу преодолеть пустую проблему возврата соответствия регулярному выражению, явно используя encoding='utf-8'
при открытиифайл данных.