如何利用Excel内置功能或Python库实现不规则俄文地址数据的标准化格式化?
如何利用Excel内置功能或Python库实现不规则俄文地址数据的标准化格式化?
看起来你手里的俄文地址数据格式真的挺混乱的——邮编混在任意位置、大小写不统一、缩写和前缀的顺序颠三倒四,想要整理成规整的格式确实让人头大!我来给你分享两种实用的解决思路,不管是用Excel内置功能手动整理,还是用Python写代码批量处理,都能帮你搞定问题。
一、用Excel内置功能手动处理(适合数据量不大的情况)
如果你的数据行数不多,用Excel的自带功能慢慢清理也能达到效果,步骤如下:
- 步骤1:拆分数据
选中地址列,用「数据」选项卡下的「文本分列」功能,按「逗号」作为分隔符,把每个地址元素拆分到单独的列里。 - 步骤2:清理冗余内容
用TRIM()函数去掉每个单元格的多余空格,比如在辅助列输入=TRIM(A1);然后用IF()函数过滤空值和不需要的内容(比如“россия”、6位邮编),比如=IF(OR(A1="россия", ISNUMBER(VALUE(A1))), "", A1)。 - 步骤3:规范格式和大小写
俄文的大小写可以用PROPER()函数统一每个单词首字母大写,比如=PROPER(B1);对于“санктпетербург г”这种前缀后置的情况,手动替换成“г. Санкт-Петербург”,或者用SUBSTITUTE()函数批量处理。 - 步骤4:拼接规整地址
先筛选出包含「г.」「с.」(城市/村镇)、「ул.」「пер.」(街道/小巷)、「д.」(房屋)、「кв.」(公寓)的列,然后按顺序用&拼接,比如=C1&", "&D1&", "&E1&", "&F1。
💡 缺点:Excel处理不规则列顺序比较麻烦,比如有的行邮编在第一列,有的没有,需要手动调整列的匹配关系,数据量大的话效率不高。
二、用Python批量处理(适合数据量大的情况)
你已经尝试用Python写了正则,但效果只有50/50,主要是因为地址组件的顺序太不固定了。我给你优化一下思路,不依赖固定的列顺序,而是通过识别地址元素的前缀来整理:
优化后的Python代码
import re def normalize_address_part(part): """标准化单个地址片段:修正前缀、大小写、格式""" part = part.strip() if not part or part.lower() == "россия": return None # 定义地址前缀的映射,处理前缀前置/后置的情况 prefix_map = { "г": "г.", "с": "с.", "пер": "пер.", "ул": "ул.", "д": "д.", "кв": "кв." } # 处理前缀后置的情况,比如"санктпетербург г" → "г. Санкт-Петербург" suffix_prefix_match = re.search(r"\s+([гсперулдкв])$", part.lower()) if suffix_prefix_match: prefix_key = suffix_prefix_match.group(1) main_content = re.sub(r"\s+[гсперулдкв]$", "", part) normalized = f"{prefix_map[prefix_key]} {main_content.title()}" # 处理前缀前置的情况,比如"г.видное" → "г. Видное" elif re.match(r"[гсперулдкв]\.", part.lower()): prefix, main_content = re.split(r"\.", part, maxsplit=1) normalized = f"{prefix}. {main_content.title()}" else: # 其他情况直接首字母大写 normalized = part.title() # 处理特殊格式:比如"санктпетербург"添加连字符,"8б"转"8Б" normalized = normalized.replace("Санктпетербург", "Санкт-Петербург") normalized = re.sub(r"(\d+)([а-яё])", lambda m: f"{m.group(1)}{m.group(2).upper()}", normalized) return normalized def process_single_address(line): """处理单条地址行,输出规整后的结果""" # 先移除所有6位邮编 line_clean = re.sub(r"\b\d{6}\b", "", line) # 按逗号拆分并过滤空值 raw_parts = [p.strip() for p in line_clean.split(",") if p.strip()] # 标准化每个地址片段 valid_parts = [part for part in map(normalize_address_part, raw_parts) if part] # 按地址组件的优先级排序:城市/村镇 → 街道/小巷 → 房屋 → 公寓 def get_part_priority(part): priority_order = { "г.": 0, "с.": 0, "ул.": 1, "пер.": 1, "д.": 2, "кв.": 3 } for prefix, prio in priority_order.items(): if part.startswith(prefix): return prio return 4 # 未知组件放最后 valid_parts.sort(key=get_part_priority) # 拼接成最终地址字符串 return ", ".join(valid_parts) # 测试你的地址数据 address_list = [ "россия, московская область, ленинский район, г.видное, ул.заводская, д.6, кв.22", "643,163000,78,,санктпетербург г,,офицерский пер,8б,,5", "646602, россия, омская обл. , горьковский р-н, с. астыровка, ул. комсомольская, д. 17, кв. 1", "656000, россия, г. барнаул, ул. эмилии алексеевой, д. 6, кв. 108" ] for addr in address_list: print(process_single_address(addr))
代码说明
normalize_address_part函数:负责把每个地址片段修正成标准格式,比如把“офицерский пер”改成“пер. Офицерский”,“8б”改成“8Б”,同时处理俄文的大小写和特殊地名(比如圣彼得堡的连字符)。process_single_address函数:先过滤掉邮编和国家名,然后把剩下的片段标准化,再按「城市→街道→房屋→公寓」的顺序排序拼接,确保输出的格式统一。- 运行这段代码后,就能得到你想要的规整地址了,比你之前的正则方案更灵活,能适配各种混乱的输入格式。
备注:内容来源于stack exchange,提问作者dynamic.aerospace.inc
相关产品推荐
相关产品推荐

