验证姓名与邮箱姓名时出错,求R代码问题排查(支持动态分隔符)
问题诊断与修正方案
让我们一步步拆解你的代码问题,以及如何修复它:
主要问题点
1. Name列与Email反转后的格式不匹配
你的name列格式是"last, first"(比如"ali, wing sam"),但你直接用原始的name字符串和反转后的email_name_rev(格式是last.middle.first)做相等判断,两者的分隔符不同(一个是, ,一个是.),自然无法匹配。
2. Email前缀中的干扰字符未清理
- 第一个Email的前缀包含数字
1(sam.wing.ali1),你没有去除这些非字母数字的干扰字符,导致反转后和name无法匹配。 - 第二个Email的前缀末尾有空格(
nick.jone),提取时会包含空格,同样造成匹配失败。
3. 固定拆分Email前缀的局限性
你用separate把Email前缀固定拆成f,s,l三段,但Email前缀的段数可能不固定(比如r.mush只有两段),这会导致反转后的字符串出现多余的点(比如.mush.r),影响匹配。
修正后的代码
library(dplyr) library(stringr) df <- data.frame( name= c("ali, wing sam","nick, jone","mak, liam","r, mush","sink, dude"), Email = c("sam.wing.ali1@xyz.com","nick.jone @xyz.com","liam.mak@xyz.com","r.mush@xyz.com","dude.sink@xyz.com") ) separator = ", " df %>% # 统一转小写,并清理Email中的空格 mutate( across(c(name, Email), tolower), Email = str_squish(Email) ) %>% # 提取@前的部分,去除非字母数字的字符(除了点) mutate(email_prefix = str_extract(Email, '.*(?=@)'), email_prefix_clean = str_remove_all(email_prefix, '[^a-z\\.]')) %>% # 将Email前缀拆分成片段,反转后用点连接 mutate(email_name_rev = str_c(rev(str_split(email_prefix_clean, "\\.")[[1]]), collapse = ".")) %>% # 将name列转换成和email_name_rev一致的格式:last.middle.first mutate(name_formatted = str_replace_all(name, separator, "."), name_formatted = str_replace_all(name_formatted, " ", ".")) %>% # 判断是否匹配(两种情况:原始Email前缀清理后和name格式化后,或者反转后的匹配) mutate(match1 = +(name_formatted == email_name_rev | name_formatted == email_prefix_clean)) %>% # 按需选择列 select(name, Email, name_formatted, email_name_rev, match1)
代码说明
- 清理Email空格:用
str_squish去除Email中的多余空格,避免提取前缀时包含空格。 - 清理Email前缀干扰字符:用
str_remove_all去除前缀中的非字母和点的字符(比如数字1)。 - 动态反转Email前缀:用
str_split把前缀拆成列表,再用rev反转后用str_c连接,适配任意段数的前缀。 - 格式化Name列:把
name列中的,和空格都替换成.,转换成和Email反转后一致的格式。 - 匹配逻辑修正:对比格式化后的name和反转后的Email前缀,或者格式化后的name和清理后的原始前缀(覆盖不同的Email命名规则)。
内容的提问来源于stack exchange,提问作者newcomer
相关产品推荐
相关产品推荐

