如果子字符串在另一个向量中具有完全匹配,则提取子字符串

时间:2015-01-30 19:54:34

标签: regex r

更新 :此问题的第一个版本隐含地询问如果在另一个字段中 ANY 匹配,则如何提取子字符串矢量,为@Colonel Beauvel提供了一个优雅的回应:

  

这就是诀窍,基础R

newname = sapply(nametitle, function(u){
    bool = sapply(name, function(x) grepl(x, u))
    if(any(bool)) name[bool][1] else NA })

newname 
John Smith, MD PhD       Jane Doe, JD 
            "John"             "Jane"

然而,我没有意识到我实际上是在寻找一种方法来找到精确匹配,直到该函数提供的功能对我的向量中的所有元素都不起作用。因此,以下是我修改过的问题。


说我有以下通用名称的字符向量及其学位:

nametitle <- c("John Smith, MD PhD", "Jane Doe, JD", "John-Paul Jones, MS")

我有一个名字的“查找”矢量:

name <- c("John", "Jane", "Mark", "Steve")

我想要做的是搜索nametitle的每个元素,如果元素的一部分(即每个字符串的子字符串)与name中的元素完全匹配,那么新向量newname,将nametitle的元素写为name的对应元素,或者如果没有完全匹配,则从nametitle写入原始值。

因此,我期望正确的功能是返回newname以下三个元素:

[1] "John" [2] "Jane" [3] "John-Paul Jones, MS"

我使用上面提供的功能尝试了以下内容:

newname = sapply(nametitle, function(u){
  bool = sapply(name, function(x) grepl(x, u))
  if(any(bool)) name[bool][1] else NA })

对于元素"John Smith, MD Phd""Jane Doe, JD"执行得很好,但对"John-Paul Jones, MS"不适用 - 此元素在新向量"John"中替换为newname

可能会对@Colonel Beauvel提供的原始函数进行简单的更改来解决此问题,但使用嵌套的sapply函数会让我经历一个循环(双关语意图?)。感谢。

2 个答案:

答案 0 :(得分:2)

这就是诀窍,基础R

newname = sapply(nametitle, function(u){
    bool = sapply(name, function(x) grepl(x, u))
    if(any(bool)) name[bool][1] else NA
})

#>newname
#John Smith, MD PhD       Jane Doe, JD 
#            "John"             "Jane" 

答案 1 :(得分:1)

这是一个简单的方法。首先,根据name向量创建正则表达式模式:

pattern <- paste0(".*(?<=\\s|^)(", paste(name, collapse = "|"), ")(?=\\s|$).*")
# [1] ".*(?<=\\s|^)(John|Jane|Mark|Steve)(?=\\s|$).*"

如果使用此模式,单个sub命令将起到作用:

sub(pattern, "\\1", nametitle, perl = TRUE)
# [1] "John"                "Jane"                "John-Paul Jones, MS"