python2.7 在使用正则表达式来匹配中文字符时,经常会出现意想不到的问题,比如下面这个匹配问题:
1、问题
字符串:
飞利浦(PHILIPS)
飞利浦(PHILIPS)
飞利浦(PHILIPS)
飞利浦(PHILIPS)
从字符串中将"飞利浦"和"PHILIPS"提取出来。
注意:
字符串中将"PHILIPS"括起来的括号有中文括号也有英文括号
很自然的使用下面的正则表达式进行匹配:
s = "飞利浦(PHILIPS)"
ptn = re.compile(r"(.*?)[\((](.*?)[)\(]")
res = ptn.search(s)
print res.group(1)
print res.group(2)
这里使用[\((]和[)\(] 本意是匹配中文括号或者英文括号,但是这样是错误的。
如果这里使用的utf-8编码,'
[\((]'被解释成了'[\(\xef\xbc\x88]',
在进行字符串匹配时
'
[\((]'的意思是:出现英文括号或者\xef或者\xbc或者\x88
显然,这样对源字符串进行匹配时,就无法获取到想到的信息
2、解决方法一
这里需要使用unicode编码对字符串中的中文括号进行匹配,
即使用unicode编码的正则表达式,同时原字符串也要转换成unicode编码,
当需要将结果输出到文件时,匹配的结果也要从匹配好的unicode编码转换成合适的编码格式。
解决代码如下,这里假设文件的编码格式是UTF-8的:
fw = open("res", "w")
s = "飞利浦(PHILIPS)"
ptn = re.compile(ur"(.*?)[\((](.*?)[)\)]")
res = ptn.search(s.decode("UTF-8"))
fw.write("%s|%s\n" %(res.group(1).encode("UTF-8"), res.group(2).encode("UTF-8")))
fw.close()
3、解决方法二
这里使用[ ]作为逻辑或的匹配符号,也是不太合适的,这里可以考虑使用 | 来替换 [ ]。
但是使用 | 是要注意使用小括号将逻辑或的匹配括起来,代码如下
fw = open("res", "w")
s = "飞利浦(PHILIPS)"
ptn = re.compile(ur"(.*?)(\(|()(.*?)()|\))")
res = ptn.search(s)
fw.write("%s|%s\n" %(res.group(1), res.group(3)))
fw.close()