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

在R语言中拆分数据框列:提取姓名、姓氏与出生日期

解决办法:利用正则精准拆分三部分

你的问题出在之前的处理只拆分了名字和「姓氏+生日」的组合,没把末尾的8位生日数字单独拆分出来。我们可以利用固定格式的生日(8位数字在末尾)和名字/姓氏的大小写规则来精准拆分。

方法一:分步拆分(先拆生日,再拆姓名)

先把末尾8位数字提取为Birthdate,剩下的部分再拆分为Name和Lastname:

library(dplyr)
library(tidyr)

# 构造示例数据框
df <- data.frame(User = c("JohnLenon03041965", "RogerFederer12021954", "RickLandsman01041975"))

# 第一步:拆分出Birthdate和姓名组合
df <- df %>%
  mutate(
    Birthdate = sub(".*(\\d{8})$", "\\1", User),  # 提取末尾8位数字
    NameLast = sub("(\\d{8})$", "", User)        # 去掉末尾8位,得到姓名组合
  )

# 第二步:拆分姓名组合为Name和Lastname
df <- df %>%
  separate(NameLast, into = c("Name", "Lastname"), sep = "(?=[A-Z])")  # 在大写字母前拆分

# 整理列顺序并去掉临时列
df <- df %>% select(Name, Lastname, Birthdate)

运行后得到的结果就是你想要的:

Name Lastname Birthdate
1   John    Lenon 03041965
2  Roger  Federer 12021954
3   Rick Landsman 01041975

方法二:一次性拆分(用正则匹配三部分)

如果你想一步到位,可以用separate配合更精准的正则表达式,直接把User列拆成三列:

df %>%
  separate(User, into = c("Name", "Lastname", "Birthdate"), 
           sep = "(?<=[a-z])(?=[A-Z])|(?<=[A-Za-z])(?=\\d{8})")

这里的正则表达式解释:

  • (?<=[a-z])(?=[A-Z]):匹配小写字母后面、大写字母前面的位置(用来拆分名字和姓氏,比如John和Lenon之间)
  • (?<=[A-Za-z])(?=\\d{8}):匹配字母后面、8位数字前面的位置(用来拆分姓氏和生日,比如Lenon和03041965之间)

为什么之前的代码没成功?

你之前的gsub('([[:upper:]])', ' \\1', df$User)会给所有大写字母前加空格,包括开头的J/R/R,导致字符串开头多了空格,而且生日部分是数字,没有大写字母,所以不会被拆分,最后separate只能把名字和「姓氏+生日」分开,没法拆分生日。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:23:04