You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Pandas str.contains时字符集与Em破折号的正则异常问题

军衔正则筛选异常的原因与解决方案

问题背景

使用Pandas的str.contains结合正则筛选低阶军衔时,原正则r'e[ -–]*[123]'(意图匹配e3、e 3、e-2、e––1这类格式)出现误匹配:

  • 错误匹配了E-6/ Petty Officer 1st class(因字符串中包含1st的1)
  • 错误匹配了eajucbniuawbnciu1(因末尾的1)

测试代码及输出如下:

data = {
    'Rank': ['E-3', 'e2', 'E 1', 'E7', 'E-5 ','e-6 petty officer 1st class'],
}

import pandas as pd

filter_lower_enlisted = r'e[ -–]*[123]'

participants = pd.DataFrame(data)

parts_enlisted_low = participants[participants['Rank'].str.contains(filter_lower_enlisted, case=False, na=False)].reset_index(drop=True)
print(parts_enlisted_low['Rank'])

输出:

0                            E-3
1                             e2
2                            E 1
3    e-6 petty officer 1st class
Name: Rank, dtype: object

异常原因

正则字符集[ -–]的写法存在本质问题:
短破折号(-)被放在了空格(ASCII 32)和Em破折号(Unicode 8212)之间,此时正则引擎会将其解析为字符范围(从ASCII 32到Unicode 8212),而非单独的短破折号字符。

这个范围覆盖了几乎所有可打印字符(包括字母、数字、普通符号等),导致[ -–]*可以匹配任意数量的这类字符。只要字符串中存在不区分大小写的e,且后续任意位置出现1/2/3,就会被错误匹配。比如e-6 petty officer 1st class中的1st的1、eajucbniuawbnciu1末尾的1,都触发了匹配。

可行解决方案

1. 调整短破折号在字符集的位置

将短破折号放在字符集的开头或结尾,避免被解析为范围:

# 短破折号放在开头
filter_lower_enlisted = r'e[- –]*[123]'
# 或放在结尾
filter_lower_enlisted = r'e[ –-]*[123]'

2. 转义短破折号

在短破折号前添加反斜杠,明确标记为普通字符:

filter_lower_enlisted = r'e[ \-–]*[123]'

3. 拆分正则表达式

用或逻辑分隔不同分隔符的匹配规则,彻底规避字符范围问题:

filter_lower_enlisted = r'e[ –]*[123]|e[- ]*[123]'

4. 增强匹配严谨性(可选)

如果需要严格匹配军衔格式(而非字符串任意位置的e+1/2/3),可以添加边界限制:

  • 匹配单词边界:确保e和数字是一个独立的军衔标识
    filter_lower_enlisted = r'\be[- –]*[123]\b'
    
  • 匹配行开头:如果军衔总是出现在字符串开头
    filter_lower_enlisted = r'^e[- –]*[123]'
    

内容的提问来源于stack exchange,提问作者Noot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 21:23:29