我认为我在理解R中的正则表达式时可能会遇到一些问题。
我需要从样本向量中提取电话号码和姓名,并使用Stringer软件包功能创建一个具有相应列的名称和号码数据框。
以下是我的样本向量。
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)
它不起作用,因为它将姓名中的数字与电话号码合并在一起。 (也不是最佳代码)
在解释完成此任务的最简单方法方面,我将提供一些帮助。
答案 0 :(得分: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
答案 1 :(得分:1)
我认为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("-")
这样,您就不会因为数字中出现的连字符数量而被锁定为固定格式(我建议的正则表达式允许使用任何数字)。
答案 2 :(得分:0)
如果您(像我一样)更喜欢使用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"