_str.contains() 默认按正则匹配,含元字符会误解析;需字面匹配时必须设 regex=False 和 na=False,并注意大小写与空值处理。
为什么
有时不匹配明明存在的数据
默认情况下,
把输入当正则表达式处理,而
、
、
虽然本身不是元字符,但一旦你写
或
就会意外触发正则逻辑,导致匹配失败或误匹配。更常见的是字符串里有
、
、
、
、
、
、
这类字符,直接传进去会被解释成正则语法,而不是字面意思。
实操建议:
如果只是想查纯文本子串(比如找包含 "user_id=123" 的日志),务必加参数
:
如果真要用正则(比如匹配邮箱、手机号),必须确认字符串已转义或用原始字符串:用
而不是
空值(
)默认返回
,导致布尔索引出错;加
更安全:
的
和
参数怎么选
大小写敏感是默认行为,但业务数据常混用大小写,比如搜索 "ERROR" 却漏掉 "error" 或 "Error"。这时候不设
就会丢行。
空值处理更隐蔽:Pandas 对
做布尔运算时返回
,而
会把
当作
吗?不会——它直接让整行被过滤掉(取决于上下文),但更稳妥的做法是明确控制。
等价于底层调用
再匹配,性能略低,但对用户友好;若列很长且确定大小写统一,可省略
表示把所有空值视为
;
视为
;不传则保留
,在布尔索引中可能引发
类警告
组合常用写法:
用正则时,
、
、
这些边界符为啥不生效
因为
本质是检查“是否在字符串中出现”,它等价于
,不是
。所以
并不是“以 abc 开头”,而是“从任意位置开始能匹配到一个以 abc 开头的子串”——这几乎总为真;同理
也不代表“以 abc 结尾”,而是“存在某个位置,后面紧跟着 abc 且那是字符串末尾”,语义容易绕晕。
要真正匹配开头,用
,快且语义清晰
要匹配结尾,用
要单词边界(如只匹配独立的 "cat" 而非 "scatter" 中的 cat),必须用
并写
,且确保
(默认就是 True,但显式写出更防错)
性能提示:正则边界符本身不慢,但
在 Unicode 字符串中行为复杂,中文文本慎用;英文场景下没问题
匹配中文、emoji 或特殊符号时要注意什么
中文和 emoji 不是问题本身,问题是它们常和正则元字符共存,或者被错误地当成字节处理。比如
中的
会被当量词,
中的 emoji 是合法 Unicode 字符,但某些旧版 Pandas 对 surrogate pair 支持不稳定。
含特殊符号的字面匹配,坚持
最省心
必须用正则匹配中文时,避免用
(它不一定匹配中文),改用
或
显式声明范围
Pandas 1.3+ 对 emoji 支持较好,但若遇到
或匹配异常,先检查列 dtype 是否为
(不是
);用
可提升一致性
不确定编码时,先试
—— 但这是下策,优先保证源头数据编码干净
事情说清了就结束。最常踩的坑不是不会写正则,而是忘了
和
这两个开关——它们不显眼,但一漏就查半天。
_str.contains('abc')_str.contains()abc'a.c''ab?c'.+*?[^$regex=Falsedf[df['log'].str.contains('user_id=123', regex=False)]r'd{3}-d{4}''\d{3}-\d{4}'NaNNaNna=False.str.contains('abc', regex=False, na=False)_str.contains()casenacase=FalseNaNNaNdf[condition]NaNFalsecase=Falsestr.lower()na=FalseFalsena=TrueTrueNaNBoolean Series key will be reindexeddf['col'].str.contains('abc', case=False, regex=False, na=False)^$_str.contains()re.search(pattern, string)re.match()^abcabc$str.startswith('abc')str.endswith('xyz')regex=Truer'cat'regex=True'你好+'+'⚠️abc'regex=False.[u4e00-u9fa5][wu4e00-u9fa5]UnicodeDecodeErrorobjectstringdf['col'] = df['col'].astype('string')df['col'].str.encode('utf-8').str.contains(...)regex=Falsena=False