
本文介绍如何利用 str.replace() 配合正则表达式,精准移除 Pandas Series 中每个字符串末尾最后一个连字符(-)及其右侧所有字符,保留前面部分,且对不含匹配模式的字符串完全无影响。
本文介绍如何利用 `str.replace()` 配合正则表达式,精准移除 pandas series 中每个字符串末尾**最后一个连字符(-)及其右侧所有字符**,保留前面部分,且对不含匹配模式的字符串完全无影响。
在数据清洗中,常需处理类似 FUHV2-DEN、FUHV2-FOO-DEN 这类含多个连字符的标识符,并仅剔除末尾的 -XXX 后缀(如 -DEN、-FOO),而保留中间的连字符(如 FUHV2-FOO)。此时,使用 str.split('-').str[:-1].str.join('-') 虽看似直观,但存在明显缺陷:它会错误地将 FUH07V2NUM(无连字符)拆分为 [FUH07V2NUM],取 [:-1] 后变为空列表,最终连接为空字符串 —— 导致数据丢失。
✅ 推荐方案是使用 str.replace() 配合锚定正则表达式:
df['out'] = df['ID'].str.replace(r'-[^-]*$', '', regex=True)
正则解析:
- - :匹配字面量连字符;
- [^-]* :匹配零个或多个非连字符(确保捕获的是最后一个 - 之后的内容);
- $ :行尾锚点,强制匹配必须发生在字符串最末端;
- 整体 r'-[^-]*$' 精确命中“末尾的连字符 + 其后所有非连字符”,替换为空字符串即实现“切除”。
效果示例: | Name1 | ID | ID_SPLIT | ID_SPLIT2 | out | |--------|---------------|----------|-----------|-----------| | FUH-V2 | FUH07V2NUM | None | None | FUH07V2NUM | | FUH-V2 | FUHV2-DEN | FUHV2 | FUHV2 | FUHV2 | | FUH-V2 | FUH30V2NUM | None | None | FUH30V2NUM | | FUH-V2 | FUHV2-FOO-DEN | None | None | FUHV2-FOO |
⚠️ 注意事项:
- 必须显式设置 regex=True(Pandas 1.4+ 默认为 True,但为兼容性和可读性建议保留);
- 正则使用原始字符串 r'' 避免转义干扰;
- 该操作是安全的:若字符串不满足 -XXX 结尾模式(如无 - 或 - 不在末尾),则原样保留,零副作用。
此方法简洁、高效、语义明确,是处理“末尾特定分隔符截断”任务的标准实践。











