【问题标题】:extracting names and numbers using regex使用正则表达式提取名称和数字
【发布时间】:2018-07-04 01:22:10
【问题描述】:

我想我在理解 R 中的正则表达式时可能会遇到一些问题。

我需要从样本向量中提取电话号码和姓名,并使用 stringr 包功能创建一个数据框,其中包含姓名和号码的对应列。

以下是我的样本向量。

phones <- c("Ann 077-789663", "Johnathan 99656565",
            "Maria2 099-65-6569 office")

我想出的提取这些的代码如下

numbers <- str_remove_all(phones, pattern = "[^0-9]")
numbers <- str_remove_all(numbers, pattern = "[a-zA-Z]")
numbers <- trimws(numbers)

names <- str_remove_all(phones, pattern = "[A-Za-z]+", simplify = T)

phones_data <- data.frame("Name" = names, "Phone" = numbers)

它不起作用,因为它需要名称中的数字并与电话号码连接。 (也不是最优代码)

在解释完成此任务的最简单方法时,我将不胜感激。

【问题讨论】:

  • @Onyambu 你能解释一下吗?
  • strcapture("(\\w+)\\s(\\S+)",phones,data.frame(names=character(),phone=character()))
  • read.table(text=phones,col.names = c("names","phone","office"),fill=T)
  • 这个问题是我只需要使用“stringr”包的名称,其中没有数字,数字中没有破折号。无论如何,谢谢。
  • data.frame(names=str_extract(phones,"^\\w+"),phones=str_extract(phones,"\\b\\d[^ ]*"))

标签: r regex stringr


【解决方案1】:

不是正则表达式专家,但是使用stringr 包,我们可以提取其中带有可选“-”的数字模式,并将“-”替换为空字符串以提取没有任何“-”的数字。对于名称,我们提取字符串开头的第一个单词。

library(stringr)
data.frame(Name = str_extract(phones, "^[A-Za-z]+"), 
           Number = gsub("-","",str_extract(phones, "[0-9]+[-]?[0-9]+[-]?[0-9]+")))


#       Name    Number
#1       Ann 077789663
#2 Johnathan  99656565
#3     Maria 099656569

如果您想完全坚持使用stringr,我们可以使用str_replace_all 而不是gsub

data.frame(Name = str_extract(phones, "[A-Za-z]+"), 
Number=str_replace_all(str_extract(phones, "[0-9]+[-]?[0-9]+[-]?[0-9]+"), "-",""))

#       Name    Number
#1       Ann 077789663
#2 Johnathan  99656565
#3     Maria 099656569

【讨论】:

  • 这很有帮助,我给你最好的答案。然而,还有一个问题?如果我不使用 gsub(),它会与 str_replace() 保持相似的结果吗?
  • @MarkHovsepyan 实际上,我们需要使用 str_replace_all 来代替。更新了答案。
【解决方案2】:

我认为 Ronak 的回答对于名称部分来说是很好的,我真的没有很好的选择。

对于数字,我会使用“数字和连字符,两端都有单词边界”,即

numbers = str_extract(phones, "\\b[-0-9]+\\b") %>%
    str_remove_all("-")
# Can also specify that you need at least 5 numbers/hyphens 
# in a row to match
numbers2 = str_extract(phones, "\\b[-0-9]{5,}\\b") %>%
    str_remove_all("-")

这样,您就不会被固定在数字中出现的连字符数的固定格式中(我建议的正则表达式允许任何数字)。

【讨论】:

  • 是的,这非常有效,在这种情况下,我将使用您的正则表达式模式,以提高可重用性!
【解决方案3】:

如果您(像我一样)更喜欢使用 base-R 并希望使正则表达式尽可能简单,您可以这样做:

phone_split <- lapply(
  strsplit(phones, " "), 
  function(x) {
    name_part <- grepl("[^-0-9]", x)
    c(
      name = paste(x[name_part], collapse = " "),
      phone = x[!name_part]
    )
  }
)
phone_split
[[1]]
        name        phone 
       "Ann" "077-789663" 

[[2]]
       name       phone 
"Johnathan"  "99656565" 

[[3]]
           name           phone 
"Maria2 office"   "099-65-6569" 

do.call(rbind, phone_split)

     name            phone        
[1,] "Ann"           "077-789663" 
[2,] "Johnathan"     "99656565"   
[3,] "Maria2 office" "099-65-6569"

【讨论】:

    猜你喜欢
    • 2018-07-20
    • 2015-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-24
    • 2022-01-06
    相关资源
    最近更新 更多