Python中使用正则表达式查找替换子串的问题求助
问题描述
刚接触正则表达式,需解决Python+pandas处理Excel时的地址子串替换问题:
- 用pandas读取Excel,通过re模块(Perl风格),将地址列末尾的街道类型(如street/ave/drive等)替换为指定缩写(ST/AVE/DR等)
- 示例数据:
| Site | Service | Address |
|---|---|---|
| 1 | 1 | 100 Cook Street |
| 2 | 3 | 101 Cook ave |
| 3 | 1 | 102 Cook Dr |
| 4 | 1 | 103 Cook Court |
| 5 | 2 | 104 Cook cir |
| 6 | 2 | 105 Cook drive |
- 期望输出:地址统一为
100 COOK ST、101 COOK AVE这类格式 - 当前
reformat函数存在问题:找不到合适正则匹配地址末尾的街道类型,r'\w+$'无法识别目标子串,赋值逻辑也有错误
解决方案
1. 核心正则匹配逻辑
要精准匹配地址末尾的街道类型,需满足:
- 匹配字符串末尾的街道类型,忽略大小写
- 兼容同一街道类型的不同变体(如
street/st/str都匹配为ST)
推荐使用带单词边界和结尾锚定的正则,结合re.IGNORECASE忽略大小写:
- 匹配规则:
r'\b(' + '|'.join(variants) + r')\b$',其中variants是用户输入的所有待匹配变体(如['st', 'str', 'street']) - 用
re.sub直接替换匹配部分,优先用pandas内置字符串方法,避免低效的行遍历
2. 修复后的代码实现
方式一:pandas字符串方法(高效推荐)
import pandas as pd import re def reformat_address(df, column_header, find_variants, format_to): # 构建正则:匹配末尾的街道类型,忽略大小写 pattern = r'\b(' + '|'.join(find_variants) + r')\b$' # 替换并统一转为大写 df[column_header] = df[column_header].str.replace( pattern, format_to, regex=True, flags=re.IGNORECASE ).str.upper() # 返回替换记录数 return len(df[df[column_header].str.contains(pattern, flags=re.IGNORECASE)]) # 示例调用:把street/st/str替换为ST df = pd.read_excel('your_file.xlsx') count = reformat_address(df, 'Address', ['street', 'st', 'str'], 'ST') print(f"替换了{count}条记录") # 保存结果 df.to_excel('formatted_addresses.xlsx', index=False)
方式二:修复原遍历行逻辑(保留迭代需求)
import pandas as pd import re def reformat(find_variants, format_to): count = 0 pattern = r'\b(' + '|'.join(find_variants) + r')\b$' for i, row in df.iterrows(): cell_value = str(row[column_header]) # 检查是否匹配 if re.search(pattern, cell_value, flags=re.IGNORECASE): # 替换匹配部分并转大写 new_value = re.sub(pattern, format_to, cell_value, flags=re.IGNORECASE).upper() df.at[i, column_header] = new_value count += 1 if count == 0: print("No matches found...") return count # 示例调用 df = pd.read_excel('your_file.xlsx') column_header = 'Address' count = reformat(['ave', 'avenue'], 'AVE') print(f"替换了{count}条记录")
3. 关键注意点
\b单词边界:避免误匹配(比如不会把Cookstreet里的street当成街道类型)re.IGNORECASE:统一处理大小写变体(Ave/ave/AVE都能匹配)- 优先用pandas
str.replace:比手动遍历iterrows效率高数倍,适合大文件处理 - 替换后转大写:保证输出格式完全统一
内容的提问来源于stack exchange,提问作者sweeney
相关产品推荐
相关产品推荐

