Python 如何使用正则表达式可移植地解析(Unicode)度符号?
我正在为Ubuntu上的Python 如何使用正则表达式可移植地解析(Unicode)度符号?,python,regex,unicode,portability,Python,Regex,Unicode,Portability,我正在为Ubuntu上的sensors实用程序的输出编写一个简单的正则表达式解析器。下面是我正在分析的一行文本的示例: temp1: +31.0°C (crit = +107.0°C) 下面是我用来匹配它的正则表达式(在Python中): 这段代码按预期工作,并与我上面给出的示例文本相匹配。我真正感兴趣的是数字,所以这一点: (\+|-)(\d+\.\d+)\W\WC 以匹配+或-符号开始,以匹配°C结束 我的问题是,为什么需要两个\W(非字母数字)字符来匹配°?在Unico
sensors
实用程序的输出编写一个简单的正则表达式解析器。下面是我正在分析的一行文本的示例:
temp1: +31.0°C (crit = +107.0°C)
下面是我用来匹配它的正则表达式(在Python中):
这段代码按预期工作,并与我上面给出的示例文本相匹配。我真正感兴趣的是数字,所以这一点:
(\+|-)(\d+\.\d+)\W\WC
以匹配+
或-
符号开始,以匹配°C
结束
我的问题是,为什么需要两个
\W
(非字母数字)字符来匹配°
?在Unicode与我的表示方式不同的系统上,代码是否会中断?如果是,如何使其可移植?可能的可移植解决方案:
将输入数据转换为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')]
编辑
allready在评论中指出了这一点
更新
关于输入编码的注释:
check\u output()
返回有时可能是文本的二进制数据(在本例中,该数据应具有已知的字符编码,您可以将其转换为Unicode)。无论如何,ord(u'°')==176,因此不能使用ASCII编码
因此,要将输入数据解码为unicode
,基本上*您应该使用locale.getpreferredencode()
从系统语言环境中进行编码,例如:
data = subprocess.check_output(...).decode(locale.getpreferredencoding())
正确编码数据后:
在这种情况下,不使用re.UNICODE,您将获得相同的输出
基本上为什么?因为在俄文Win7上,如果我们有将其输出解码为utf-8的
script.py
,则使用cp1251
作为preferredencoding
:
#!/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())
将产生错误的结果:“b°”
而不是°
因此,在某些情况下,您需要知道输入数据的编码。使用与
\W\WC
或\WC
不匹配的re.UNICODE
标志。或者,我误解你了吗?还有一个“℃
”,它是一个单独的字符,表示摄氏度。非常感谢,Unicode联盟!当然,但是对于这类事情,一个完整的工作示例总是一个好主意。对于许多程序员来说,即使有完整的工具,正确处理Unicode也是很困难的:(+1:用于“将输入数据转换为Unicode”。顺便说一句,在这种情况下,您将在没有re.Unicode
的情况下获得相同的输出。谢谢。我已经玩过了。在“真实”中代码数据实际上来自对子进程的调用的输出。检查输出,它返回的数据是ASCII,而不是Unicode,因此这在那里不太有效。也许更明智的做法是转移到Python3,其中“一切”都是Unicode?嗯。@snim2:检查输出()
返回有时可以是文本的二进制数据(您可以将其转换为Unicode)。无论如何,ord(u'°')==176
因此不能使用编码对其进行编码。Python 3帮不了您,因为check_output
可以返回作为文本没有意义的数据,例如二进制图像数据(无法将其转换为Unicode;没有关联的字符编码)。@reclosedev:您的意思可能是locale.getpreferredencoding()
。它完全独立于用于脚本的源编码。
subprocess.check_output(['python',
'script.py']).decode(locale.getpreferredencoding())