如何在R中使用gsub替换_A_&_B_模式中的单个字母
搞定R中公司名称的正则替换问题
我明白你要做的事:把像John_K_&_E_Scott这类字符串里的_K_&_E_改成__&__——也就是把_&_两边被下划线包着的单个字母删掉,同时绝对不能碰那些多字母的内容(比如BOYS这种,绝不能误删成OYS)。
先说说你原来代码的问题:
names[, JOINING_ID := gsub("[A-Za-z]_&_[A-Za-z]\\w", "", JOINING_ID)]
这个正则的匹配逻辑错了,它会抓单个字母 + & + 单个字母 + 任意单词字符,然后把这些内容全删掉。难怪你会遇到John_A_&_BOYS_变成John__&_OYS_的情况——它把A_&_B这部分删掉了,剩下OYS_,完全不符合需求。
正确的解决办法
我们需要精准锁定_单个字母_&_单个字母_这个模式,只替换掉中间的单个字母,留下__&__的结构。给你两个靠谱的方案:
方案1:最直接的精准匹配
直接写死匹配_X_&_Y_(X/Y是单个大小写字母),替换成__&__:
names[, JOINING_ID := gsub("_[A-Za-z]_&_[A-Za-z]_", "__&__", JOINING_ID)]
这个正则的每一部分都对应你要处理的结构,不会乱匹配其他内容。测试一下你的例子:
John_K_&_E_Scott→John__&__Scott(完美符合预期)John_A_&_BOYS_→ 完全不变(因为_BOYS_是多字母,不匹配_[A-Za-z]_,不会被误改)
方案2:用捕获组(更灵活)
如果以后你需要调整规则,比如保留某些字符,用捕获组会更清晰。这里我们捕获两个单个字母,然后替换时跳过它们:
names[, JOINING_ID := gsub("_(.)_&_(.)_", "__&__", JOINING_ID, perl = TRUE)]
这里(.)代表单个任意字符,如果你确定只有字母,把它改成([A-Za-z])会更严谨,避免误匹配数字或符号。
后续处理:去除标点
完成上面的替换后,要是你想去掉标点,直接接着用gsub就行:
# 去掉所有标点符号 names[, JOINING_ID := gsub("[[:punct:]]", "", JOINING_ID)] # 要是想保留&,就这么写: names[, JOINING_ID := gsub("[^A-Za-z0-9& ]", "", JOINING_ID)]
内容的提问来源于stack exchange,提问作者Jess
相关产品推荐
相关产品推荐

