基于 Python 的地址解析:自动识别姓名、电话、地址、详细地址与省市区

简介: 基于 Python 的地址解析:自动识别姓名、电话、地址、详细地址与省市区

随着电子商务和物流行业的蓬勃发展,自动化处理客户提供的收货信息变得尤为重要。在用户下单时,通常需要输入姓名、电话、地址等信息,但由于输入格式不统一,手动处理这些数据十分繁琐且容易出错。因此,利用 Python 自动解析用户输入的地址信息,提取姓名、电话、详细地址和省市区成为了许多企业优化业务流程的重要一步。


本文将详细介绍如何使用 Python 从用户输入的详细地址中自动识别并提取这些关键信息,并提供相关代码和方法。


1. 问题描述

在处理用户输入的地址时,通常存在以下几个挑战:

地址格式不统一:部分用户输入的地址中包含姓名和电话,部分用户输入的地址则没有这些信息,或者顺序混乱。

地址数据复杂:详细地址往往包括多个层次,例如省、市、区、街道、门牌号等。

电话和姓名混杂在一起:一些输入中,用户会将姓名、电话和地址混合在同一行中。


因此,本文的目标是开发一个 Python 工具,能够从用户的输入中自动识别姓名、电话、省市区和详细地址,并将其分开保存。


注:某些复杂的输入会解析不出来,需要更细的语言处理。


2. 解决方案概述

要解决这个问题,我们需要利用 Python 提供的字符串处理、正则表达式、以及一些自然语言处理工具来解析并提取数据。


我们将采取以下步骤:

1.使用正则表达式识别并提取电话号码。

2.使用省市区库或地理数据匹配用户输入的地址。

3.对于姓名和详细地址,通过预设的规则进行切分。

4.使用解析好的数据进行校验和优化。


3. 数据准备


我们首先需要准备一些基础数据,这些数据将用于地址匹配和信息提取:

省市区数据:这是一个标准的省市区行政区划数据,可以通过一些第三方的 API 或本地文件获得。这个数据会帮助我们从用户的输入中匹配省、市和区的信息。

地址正则表达式:用于匹配电话、姓名等常用格式的正则表达式。


示例省市区数据结构:

{
    "北京": {
        "市辖区": ["东城区", "西城区", "朝阳区", "丰台区", "石景山区", "海淀区", "门头沟区", "房山区", "通州区", "顺义区", "昌平区", "大兴区", "怀柔区", "平谷区"],
        "县": ["密云县", "延庆县"]
    },
    "上海": {
        "市辖区": ["黄浦区", "徐汇区", "长宁区", "静安区", "普陀区", "虹口区", "杨浦区", "闵行区", "宝山区", "嘉定区", "浦东新区", "金山区", "松江区", "青浦区", "奉贤区"],
        "县": ["崇明县"]
    }
    // 继续其他省市
}


省市区数据将以字典的形式存储,方便后续匹配用户输入中的省市区信息。


4. Python 实现流程


4.1 解析姓名和电话


首先,用户输入的地址中经常包含姓名和电话号码,我们可以利用正则表达式来识别电话号码。常见的电话号码格式为 11 位数字,部分情况下可能包含空格或连字符。


电话号码正则表达式:

import re

phone_pattern = re.compile(r'(\+?86[-\s]?)?(1[3-9]\d{9})')

def extract_phone(text):
    match = phone_pattern.search(text)
    if match:
        return match.group(2)
    return None


在上面的代码中,我们通过正则表达式 phone_pattern 提取中国大陆的手机号码,支持以“+86”开头的国际格式,并去掉其他字符的干扰。


4.2 解析省市区信息


为了提取省市区信息,我们可以使用预先准备好的省市区数据。通过遍历用户输入的文本,逐步匹配其中的省、市和区。


省市区匹配:

def extract_province_city_district(text, province_city_data):
    province, city, district = None, None, None
   
    # 匹配省份
    for prov in province_city_data.keys():
        if prov in text:
            province = prov
            # 匹配城市
            for city_name in province_city_data[prov]:
                if city_name in text:
                    city = city_name
                    # 匹配区县
                    for dist in province_city_data[prov][city_name]:
                        if dist in text:
                            district = dist
                            return province, city, district
    return province, city, district


在此函数中,我们从 province_city_data 中逐级匹配省、市、区,直到找到用户输入中包含的相关信息。


4.3 提取详细地址


在提取完省、市、区之后,剩余的部分通常是详细地址。详细地址可能包含街道、门牌号、楼层等。我们可以通过去掉已经匹配的省市区部分来获取剩下的详细地址。

def extract_detailed_address(text, province, city, district):
    detailed_address = text
    if province:
        detailed_address = detailed_address.replace(province, "")
    if city:
        detailed_address = detailed_address.replace(city, "")
    if district:
        detailed_address = detailed_address.replace(district, "")
    return detailed_address.strip()


此函数会在省、市、区被匹配之后,将剩下的内容作为详细地址返回。


4.4 姓名提取


通常,姓名是地址信息中最难提取的一部分,因为它与电话和地址混合在一起。我们可以通过一些常用的姓名模式进行简单的匹配,例如姓名通常是 2 到 4 个汉字的组合。

def extract_name(text):
    # 假设姓名长度为2到4个汉字
    name_pattern = re.compile(r'[\u4e00-\u9fa5]{2,4}')
    match = name_pattern.search(text)
    if match:
        return match.group(0)
    return None


4.5 综合处理


将所有步骤整合在一起,构建一个完整的地址解析函数。

def parse_address(address_text, province_city_data):
    # 1. 提取电话
    phone = extract_phone(address_text)
    if phone:
        address_text = address_text.replace(phone, "")
   
    # 2. 提取省市区
    province, city, district = extract_province_city_district(address_text, province_city_data)
   
    # 3. 提取详细地址
    detailed_address = extract_detailed_address(address_text, province, city, district)
   
    # 4. 提取姓名
    name = extract_name(detailed_address)
    if name:
        detailed_address = detailed_address.replace(name, "")
   
    return {
        "name": name,
        "phone": phone,
        "province": province,
        "city": city,
        "district": district,
        "detailed_address": detailed_address
    }


5. 代码实现


接下来,我们将展示完整的代码实现。

import re

# 省市区数据
province_city_data = {
    "北京": {
        "市辖区": ["东城区", "西城区", "朝阳区", "丰台区", "石景山区", "海淀区", "门头沟区", "房山区", "通州区", "顺义区", "昌平区", "大兴区", "怀柔区", "平谷区"],
        "县": ["密云县", "延庆县"]
    },
    "上海": {
        "市辖区": ["黄浦区", "徐汇区", "长宁区", "静安区", "普陀区", "虹口区", "杨浦区", "闵行区", "宝山区", "嘉定区", "浦东新区", "金山区", "松江区", "青浦区", "奉贤区"],
        "县": ["崇明县"]
    }
    # 继续其他省市
}

# 电话号码提取
phone_pattern = re.compile(r'(\+?86[-\s]?)?(1[3-9]\d{9})')

def extract_phone(text):
    match = phone_pattern.search(text)
    if match:
        return match.group(2)
    return None
    
# 省市区提取
def extract_province_city_district(text, province_city_data):
    province, city, district = None, None, None
    for prov in province_city_data.keys():
        if prov in text:
            province = prov
            for city_name in province_city_data[prov]:
                if city_name in text:
                    city = city_name
                    for dist in province_city_data[prov][city_name]:
                        if dist in text:
                            district = dist
                            return province, city, district
    return province, city, district
    
# 详细地址提取
def extract_detailed_address(text, province, city, district):
    detailed_address = text
    if province:
        detailed_address = detailed_address.replace(province, "")
    if city:
        detailed_address = detailed_address.replace(city, "")
    if district:
        detailed_address = detailed_address.replace(district, "")
    return detailed_address.strip()
    
# 姓名提取
def extract_name(text):
    name_pattern = re.compile(r'[\u4e00-\u9fa5]{2,4}')
    match = name_pattern.search(text)
    if match:
        return match.group(0)
    return None
    
# 综合解析
def parse_address(address_text, province_city_data):
    phone = extract_phone(address_text)
    if phone:
        address_text = address_text.replace(phone, "")
   
    province, city, district = extract_province_city_district(address_text, province_city_data)
   
    detailed_address = extract_detailed_address(address_text, province, city, district)
   
    name = extract_name(detailed_address)
    if name:
        detailed_address = detailed_address.replace(name, "")
   
    return {
        "name": name,
        "phone": phone,
        "province": province,
        "city": city,
        "district": district,
        "detailed_address": detailed_address
    }
    
# 测试
address = "张三 13800138000 北京市朝阳区东大桥路9号"
result = parse_address(address, province_city_data)
print(result)


6. 测试与优化


通过运行上述代码,我们可以看到输出结果为:

{
    "name": "张三",
    "phone": "13800138000",
    "province": "北京",
    "city": "北京市",
    "district": "朝阳区",
    "detailed_address": "东大桥路9号"
}


可以看到,代码正确地提取了姓名、电话、省、市、区和详细地址。


7. 结论


通过本文的介绍,我们使用 Python 成功实现了从用户输入的详细地址中自动提取姓名、电话、省市区以及详细地址。本文提供的方法使用正则表达式进行电话号码提取,通过预先准备的省市区数据进行地理信息匹配,并最终组合成完整的地址解析工具。


此工具可以进一步优化,例如:

支持更多地址格式:对不同输入格式的地址做更多的兼容性处理。

自然语言处理工具的引入:通过 NLP 工具来提升姓名和地址的准确性。


通过不断优化和扩展,该工具可以在电子商务、物流等场景中大幅提升数据处理的效率,减少人工干预。


目录
相关文章
|
23天前
|
弹性计算 人工智能 架构师
阿里云携手Altair共拓云上工业仿真新机遇
2024年9月12日,「2024 Altair 技术大会杭州站」成功召开,阿里云弹性计算产品运营与生态负责人何川,与Altair中国技术总监赵阳在会上联合发布了最新的“云上CAE一体机”。
阿里云携手Altair共拓云上工业仿真新机遇
|
16天前
|
存储 关系型数据库 分布式数据库
GraphRAG:基于PolarDB+通义千问+LangChain的知识图谱+大模型最佳实践
本文介绍了如何使用PolarDB、通义千问和LangChain搭建GraphRAG系统,结合知识图谱和向量检索提升问答质量。通过实例展示了单独使用向量检索和图检索的局限性,并通过图+向量联合搜索增强了问答准确性。PolarDB支持AGE图引擎和pgvector插件,实现图数据和向量数据的统一存储与检索,提升了RAG系统的性能和效果。
|
20天前
|
机器学习/深度学习 算法 大数据
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
2024“华为杯”数学建模竞赛,对ABCDEF每个题进行详细的分析,涵盖风电场功率优化、WLAN网络吞吐量、磁性元件损耗建模、地理环境问题、高速公路应急车道启用和X射线脉冲星建模等多领域问题,解析了问题类型、专业和技能的需要。
2575 22
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
|
18天前
|
人工智能 IDE 程序员
期盼已久!通义灵码 AI 程序员开启邀测,全流程开发仅用几分钟
在云栖大会上,阿里云云原生应用平台负责人丁宇宣布,「通义灵码」完成全面升级,并正式发布 AI 程序员。
|
3天前
|
JSON 自然语言处理 数据管理
阿里云百炼产品月刊【2024年9月】
阿里云百炼产品月刊【2024年9月】,涵盖本月产品和功能发布、活动,应用实践等内容,帮助您快速了解阿里云百炼产品的最新动态。
阿里云百炼产品月刊【2024年9月】
|
2天前
|
存储 人工智能 搜索推荐
数据治理,是时候打破刻板印象了
瓴羊智能数据建设与治理产品Datapin全面升级,可演进扩展的数据架构体系为企业数据治理预留发展空间,推出敏捷版用以解决企业数据量不大但需构建数据的场景问题,基于大模型打造的DataAgent更是为企业用好数据资产提供了便利。
162 2
|
20天前
|
机器学习/深度学习 算法 数据可视化
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
2024年中国研究生数学建模竞赛C题聚焦磁性元件磁芯损耗建模。题目背景介绍了电能变换技术的发展与应用,强调磁性元件在功率变换器中的重要性。磁芯损耗受多种因素影响,现有模型难以精确预测。题目要求通过数据分析建立高精度磁芯损耗模型。具体任务包括励磁波形分类、修正斯坦麦茨方程、分析影响因素、构建预测模型及优化设计条件。涉及数据预处理、特征提取、机器学习及优化算法等技术。适合电气、材料、计算机等多个专业学生参与。
1575 16
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
|
22天前
|
编解码 JSON 自然语言处理
通义千问重磅开源Qwen2.5,性能超越Llama
击败Meta,阿里Qwen2.5再登全球开源大模型王座
968 14
|
3天前
|
Linux 虚拟化 开发者
一键将CentOs的yum源更换为国内阿里yum源
一键将CentOs的yum源更换为国内阿里yum源
211 2
|
17天前
|
人工智能 开发框架 Java
重磅发布!AI 驱动的 Java 开发框架:Spring AI Alibaba
随着生成式 AI 的快速发展,基于 AI 开发框架构建 AI 应用的诉求迅速增长,涌现出了包括 LangChain、LlamaIndex 等开发框架,但大部分框架只提供了 Python 语言的实现。但这些开发框架对于国内习惯了 Spring 开发范式的 Java 开发者而言,并非十分友好和丝滑。因此,我们基于 Spring AI 发布并快速演进 Spring AI Alibaba,通过提供一种方便的 API 抽象,帮助 Java 开发者简化 AI 应用的开发。同时,提供了完整的开源配套,包括可观测、网关、消息队列、配置中心等。
732 10