python中最强大、最常用的就是字符串 str 了。当re模块进行正则匹配时,如果是中文字符就会出现问题,尤其近期项目中遇到很奇葩的问题,在win server上生成的解析文件是utf-8格式,但到win10上偏偏生成了 gb2312。 这使得匹配搜索中文字符编程了乱码。经过踩坑,总结一个通用的方法,就是先转换成unicode编码,通过Unicode编码格式进行匹配,就没问题了。不管是utf-8还是gb2312都OK的。
在str的文档中有这样的一句话:The string data type is also used to represent arrays of bytes, e.g., to hold data read from a file。也就是说在读取一个文件的内容,或者从网络上读取到内容时,保持的对象为str类型;如果想把一个str转换成特定编码类型,需要把str转为unicode,然后从unicode转为特定的编码类型如:utf-8、gb2312等。
# 新的方式转换
import chardet
def IsStrIncludeCodeTrans(src, pattern, flags=0):
"""
基于正则表达式,判断字符串是否包含预期子串
"""
# 先直接对比是否有完全或部分匹配
if src.find(pattern) > -1:
return True
# 再按正则匹配
srcCodFormat = chardet.detect(src)['encoding']
patternCodFormat = chardet.detect(pattern)['encoding']
matchSet = ['ISO-8859-8','GB2312','gb2312']
if (srcCodFormat in matchSet):
src = src.decode('gb2312')
elif (srcCodFormat in ['utf-8']):
src = src.decode('utf-8')
if (patternCodFormat in matchSet):
pattern = pattern.decode('gb2312')
elif (patternCodFormat in ['utf-8']):
pattern = pattern.decode('utf-8')
'''
try:
# src = src.decode('utf-8')
# pattern = pattern.decode('utf-8')
src = src.decode('gb2312')
pattern = pattern.decode('2312')
except Exception as e:
print('IsStrInclude: ' + str(e) + '\npattern=' + pattern)
'''
# 以Unicode编码进行匹配
matRet = re.search(pattern, src, flags)
return matRet != None
# 老方式都处理utf-8格式
def IsStrInclude(src, pattern, flags=0):
"""
基于正则表达式,判断字符串是否包含预期子串
"""
# 先直接对比是否有完全或部分匹配
if src.find(pattern) > -1:
return True
# 再按正则匹配
try:
src = src.decode('utf-8')
pattern = pattern.decode('utf-8')
except Exception as e:
print('IsStrInclude: ' + str(e) + '\npattern=' + pattern)
if re.search(pattern, src, flags) != None:
return True
return False