Ответ 1
Возможное портативное решение:
Преобразование входных данных в unicode и использование флага re.UNICODE
в регулярных выражениях.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import re
data = u'temp1: +31.0°C (crit = +107.0°C)'
temp_re = re.compile(ur'(temp1:)\s+(\+|-)(\d+\.\d+)°C\s+'
ur'\(crit\s+=\s+(\+|-)(\d+\.\d+)°C\).*', flags=re.UNICODE)
print temp_re.findall(data)
Выход
[(u'temp1:', u'+', u'31.0', u'+', u'107.0')]
ИЗМЕНИТЬ
@netvope уже указали это в комментариях к вопросу.
Обновление
Заметки из J.F. Себастьян комментарий о кодировке ввода:
check_output()
возвращает двоичные данные, которые иногда могут быть текстовыми (в этом случае должна быть известная кодировка символов, и вы можете преобразовать ее в Unicode). В любом случае ord (u '°') == 176, поэтому он не может быть закодирован с использованием кодировки ASCII.
Итак, чтобы декодировать входные данные до unicode
, в основном *, вы должны использовать кодировку из локали системы с помощью locale.getpreferredencoding()
например:
data = subprocess.check_output(...).decode(locale.getpreferredencoding())
С правильно закодированными данными:
вы получите тот же результат без re.UNICODE в этом случае.
Почему в принципе? Потому что на русском языке Win7 с cp1251
как preferredencoding
, если у нас есть, например, script.py
, который декодирует его вывод на utf-8
:
#!/usr/bin/env python
# -*- coding: utf8 -*-
print u'temp1: +31.0°C (crit = +107.0°C)'.encode('utf-8')
И нам нужно разобрать его вывод:
subprocess.check_output(['python',
'script.py']).decode(locale.getpreferredencoding())
приведет к неправильным результатам: 'В°'
вместо °
.
Поэтому вам нужно знать кодировку входных данных, в некоторых случаях.