【问题标题】:"last name, first name" -> "first name last name" in serialized strings序列化字符串中的“姓氏,名字”->“名字姓氏”
【发布时间】:2013-01-07 05:56:54
【问题描述】:

我有一堆字符串,其中包含 姓氏,名字 格式的名称列表,用逗号分隔,如下所示:

names <- c('Beaufoy, Simon, Boyle, Danny','Nolan, Christopher','Blumberg, Stuart, Cholodenko, Lisa','Seidler, David','Sorkin, Aaron')

将字符串中的所有这些名称转换为 first name last name 格式的最简单方法是什么?

【问题讨论】:

  • 总是成对的名字,还是会有不止两个名字的人?
  • 你的意思是像“胡佛,J.埃德加”?可能。非常不幸的是,相同的分隔符已被用于将姓氏与名字分开以及将名字与其他名字分开。但恐怕就是这样。正确的是(我希望......)逗号不会出现在名字或姓氏中。
  • 我认为他的示例缺少一些引号。如果单个元素包含超过 1 个名称,那么在执行简单的正则表达式之前可能需要做很多工作(拆分和重组以形成唯一名称等)。
  • @AnandaMahto:或者你的问题是每个字符串中有多少个名字?在这种情况下,答案是可能有一个,可能还有更多。
  • @ChinmayPatil 不,这个例子完全是应该的。

标签: regex string r


【解决方案1】:

(1) 在每个元素中保持相同的名称 这可以通过单个 gsub 来完成(假设名称中没有逗号):

> gsub("([^, ][^,]*), ([^,]+)", "\\2 \\1", names)
[1] "Simon Beaufoy, Danny Boyle"       "Christopher Nolan"               
[3] "Stuart Blumberg, Lisa Cholodenko" "David Seidler"                   
[5] "Aaron Sorkin"    

> gsub("([^, ][^,]*), ([^,]+)", "\\2 \\1", "Hoover, J. Edgar")
[1] "J. Edgar Hoover"

(2) 每个元素分成一个名字 如果您希望每个名字和姓氏都在一个单独的元素中,请使用 (a) 扫描

scan(text = out, sep = ",", what = "")

其中out 是上面gsub 的结果,或者直接尝试(b) strapply

> library(gsubfn)
> strapply(names, "([^, ][^,]*), ([^,]+)", x + y ~ paste(y, x), simplify = c)
[1] "Simon Beaufoy"     "Danny Boyle"       "Christopher Nolan"
[4] "Stuart Blumberg"   "Lisa Cholodenko"   "David Seidler"    
[7] "Aaron Sorkin"     

> strapply("Hoover, Edgar J.", "([^, ][^,]*), ([^,]+)", x + y ~ paste(y, x), 
+   simplify = c)
[1] "Edgar J. Hoover"

请注意,以上所有示例都使用相同的正则表达式进行匹配。

更新:删除了分隔名字和姓氏的逗号。

更新:添加代码以将每个名字和姓氏分隔成单独的元素,以防首选输出格式。

【讨论】:

  • 感谢您的详尽解释。如果可以的话,我会更多地升级它!
  • 这很酷。我没有想到正则表达式会以这种方式工作,所以我没有费心去尝试!
【解决方案2】:

我赞成@AnandaMahto 的回答,但只是为了好玩,这说明了使用scansplitrapply 的另一种方法。

names <- c(names, 'Chambers, John, Ihaka, Ross, Gentleman, Robert')

# extract names
snames <- 
lapply(names, function(x) scan(text=x, what='', sep=',', strip.white=TRUE, quiet=TRUE))

# break up names
snames<-lapply(snames, function(x) split(x, rep(seq(length(x) %/% 2), each=2)))

# collapse together, reversed
rapply(snames, function(x) paste(x[2:1], collapse=' '))

【讨论】:

    【解决方案3】:

    如果您可以确定逗号不会出现在某人的名字中,那么这可能会起作用:

    mynames <- c('Beaufoy, Simon, Boyle, Danny',
                 'Nolan, Christopher',
                 'Blumberg, Stuart, Cholodenko, Lisa',
                 'Seidler, David',
                 'Sorkin, Aaron',
                 'Hoover, J. Edgar')
    mynames2 <- strsplit(mynames, ", ")
    
    unlist(lapply(mynames2, 
                  function(x) paste(x[1:length(x) %% 2 == 0], 
                                    x[1:length(x) %% 2 != 0])))
    # [1] "Simon Beaufoy"     "Danny Boyle"       "Christopher Nolan"
    # [4] "Stuart Blumberg"   "Lisa Cholodenko"   "David Seidler"    
    # [7] "Aaron Sorkin"      "J. Edgar Hoover"        
    

    我已经在其中添加了 J. Edgar Hoover。

    如果您希望一起引用的名称保持在一起,请将 collapse = ", " 添加到您的 paste() 函数中:

    unlist(lapply(mynames2, 
                  function(x) paste(x[1:length(x) %% 2 == 0], 
                                    x[1:length(x) %% 2 != 0],
                                    collapse = ", ")))
    # [1] "Simon Beaufoy, Danny Boyle"       "Christopher Nolan"               
    # [3] "Stuart Blumberg, Lisa Cholodenko" "David Seidler"                   
    # [5] "Aaron Sorkin"                     "J. Edgar Hoover"    
    

    【讨论】:

    • 可爱,谢谢!有什么办法可以在最后把琴弦重新组合在一起吗?
    猜你喜欢
    • 2016-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多