Python中文正则表达式匹配实战:从纯真库到IP138数据解析

花开有时
花开有时
发布时间:2026-10-13 | 2人浏览过
原创

本文详细介绍如何在Python中使用中文正则表达式匹配指定中文字符串。针对GBK与UTF-8编码差异,推荐统一使用UTF-8编码以确保匹配准确性。通过两个实际案例:从纯真数据库解析省市县信息,以及从IP138网站提取ISP数据,展示了懒惰匹配和Unicode处理的关键技巧。

本文介绍了一种在Python中利用中文正则表达式精确匹配指定中文字符串的方法,旨在为相关开发者提供实用的参考方案。

应用场景背景:

核心需求是从包含中文的文本中精准提取特定的子字符串。此类需求在实际开发中极为常见,本文对此类场景进行了系统的梳理与总结。

技术难点分析:

主要挑战在于处理GBK和UTF-8等不同字符编码,尤其是在正则表达式模式(Pattern)中包含汉字时,必须谨慎处理以确保匹配正常。强烈建议统一采用UTF-8编码;若无法统一,则需根据具体情况采取相应的处理策略。

一个通用且高效的正则表达式能够显著简化代码逻辑,提升处理效率,这也是区分资深开发者与初级开发者的关键因素之一。

案例一:

本例展示了如何从QQ纯真IP数据库中解析出省、市、县等特定地理信息。所使用的正则表达式基本能满足该业务场景,其中“懒惰匹配”(使用?符号)至关重要,若处理不当可能导致结果偏差。具体细节建议读者结合代码深入理解。 核心代码如下:

#!/usr/bin/env python
#encoding: utf-8
#description: 从字符串中提取省市县等名称,用于从纯真库中解析解析地理数据
import re
import sys
reload(sys)
sys.setdefaultencoding('utf8')
#匹配规则必须含有u,可以没有r
#这里第一个分组的问号是懒惰匹配,必须这么做
PATTERN = \
ur'([\u4e00-\u9fa5]{2,5}?(?:省|自治区|市))([\u4e00-\u9fa5]{2,7}?(?:市|区|县|州)){0,1}([\u4e00-\u9fa5]{2,7}?(?:市|区|县)){0,1}'
data_list = ['北京市', '陕西省西安市雁塔区', '西班牙', '北京市海淀区', '黑龙江省佳木斯市汤原县', '内蒙古自治区赤峰市',
'贵州省黔南州贵定县', '新疆维吾尔自治区伊犁州奎屯市']
for data in data_list:
 data_utf8 = data.decode('utf8')
 print data_utf8
 country = data
 province = ''
 city = ''
 district = ''
 #pattern = re.compile(PATTERN3)
 pattern = re.compile(PATTERN)
 m = pattern.search(data_utf8)
 if not m:
  print country + '|||'
  continue
 #print m.group()
 country = '中国'
 if m.lastindex >= 1:
  province = m.group(1)
 if m.lastindex >= 2:
  city = m.group(2)
 if m.lastindex >= 3:
  district = m.group(3)
 out = '%s|%s|%s|%s' %(country, province, city, district)
 print out

程序运行结果截图

案例二:

本例演示如何从IP138网站获取指定IP地址的地理位置及相关信息。

IP138是常用的IP查询平台。为了获取每个IP对应的ISP(互联网服务提供商)信息,需要对该网站页面进行解析。

经搜索发现,IP138并未提供返回JSON格式的标准API接口,因此只能通过解析HTML页面来获取数据。虽然使用DOM解析指定div标签是常规思路,但效率较低。更简洁高效的方式是利用中文正则表达式,直接从返回的HTML中提取“本站主数据:”后的关键信息。

以下是经过测试验证的实现代码:

#!/usr/bin/env python
#encoding: utf-8
#date: 2016-03-31
#note: 测试中遇到的问题,请求指定的链接会有超时现象,可以多请求几次
import requests, re
import sys
reload(sys)
sys.setdefaultencoding('utf8')
IP138_API = 'http://www.ip138.com/ips138.asp?ip='
PATTERN = ur'<li>本站主数据:(.*?)</li>'
def query_api(url):
 data = ''
 r = requests.get(url)
 if r.status_code == 200:
  data = r.content
 return data
def parse_ip138(html):
 #只能是unicode编码,不能在后面再转换为utf-8,否则无法正则匹配上.
 html = unicode(html, 'gb2312')
 #html = unicode(html, 'gb2312').encode('utf-8')
 #print html
 pattern = re.compile(PATTERN)
 m = pattern.search(html)
 if m:
  print m.group(1)
 else:
  print 'regex match failed'
if __name__ == '__main__':
 url = IP138_API + '14.192.60.0'
 resp = query_api(url)
 if not resp:
  print 'no content'
 parse_ip138(resp)

代码运行效果截图

补充说明:以下提供两款实用的正则表达式在线工具供参考:

JavaScript正则表达式在线测试工具: http://tools.jb51.net/regex/javascript

正则表达式在线生成工具: http://tools.jb51.net/regex/create_reg

如需了解更多Python相关知识,可参考本站系列教程:《Python正则表达式用法总结》、《Python数据结构与算法教程》、《Python Socket编程技巧总结》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》、《Python入门与进阶经典教程》以及《Python文件与目录操作技巧汇总》。

希望上述内容能对各位Python程序员的开发工作有所帮助。

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表