Возможное портативное решение:
Преобразование входных данных в 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')]
EDIT
@ netvope уже указал это в комментариях к вопросу.
Обновление
Примечания от JF Sebastian комментарии о кодировке ввода:
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())
приведет к неправильным результатам: 'В°'
вместо °
.
Поэтому в некоторых случаях вам необходимо знать кодировку входных данных.