R 基于所有大写字母与正常大小写的单独名称字符串



我有一个全名列表,其中姓氏全部大写,名字是正常大小写。我想使用单独的功能将其分为姓氏和名字。我不擅长正则表达式,虽然尝试了一些事情,但没有一件完全正确。下面是一个示例:

my_column_of_names <- c("DI VICENZO John", "SMITH Anne Marie", "O'ROURKE Paddy", "MARTIN-JONES Jim Rae")

任何想法都值得赞赏。

使用tidyr的函数extract

library(tidyr)
library(dplyr)
data.frame(my_column_of_names) %>%
extract(my_column_of_names,
into = c("Family", "First"),
regex = "([A-Z\s'-]+(?![a-z]))[,\s]+(.*)")
Family      First
1   DI VICENZO       John
2        SMITH Anne Marie
3     O'ROURKE      Paddy
4 MARTIN-JONES    Jim Rae

regex的工作原理:

本质上,我们将字符串分为两个捕获组,一个用于Familiy名称,一个用于First名称;它们之间的内容在regex中被"提及",但未捕获,因此未提取:

  • ([A-Z\s'-]+(?![a-z])):第一个捕获组,匹配出现一次或多次的任何大写字母、空格、连字符和撇号,除非紧接下一个字符为小写(此限制在负前瞻(?![a-z])中表示)
  • [,\s]+:逗号或/和空格出现一次或多次
  • (.*):第二个捕获组,它匹配前一个捕获组之后的任何内容

编辑

以下是tidyr的函数separate如何完成这项工作:

data.frame(my_column_of_names) %>%
separate(my_column_of_names,
into = c("Family", "First"),
sep = "(?<=[A-Z][A-Z])\s+(?=[A-Z][a-z])|,\s")

extract不同, 的工作原理是完整地描述字符串并使用捕获组分隔感兴趣的位,separate通过定义拆分点来工作。在本例中,这需要一些正则表达式语法:

在这里,我们定义了两个替代的拆分点:

  • (?<=[A-Z][A-Z])\s+(?=[A-Z][a-z]):第一个分割点 - 出现一次或多次的空格,即 (i) 前面有两个大写字母,(ii) 后跟一个大写字母和一个小写字母
  • |: 交替标记
  • ,\s:第二个分割点 - 一个简单的逗号后跟空格

最新更新