извлечение имен и номеров с помощью регулярных выражений - PullRequest
0 голосов
/ 04 июля 2018

Думаю, у меня могут возникнуть проблемы с пониманием регулярных выражений в 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)

Он не работает, так как он берет цифру в имени и соединяется с номером телефона. (тоже не оптимальный код)

Буду признателен за помощь в объяснении простейшего способа выполнения этой задачи.

Ответы [ 3 ]

0 голосов
/ 04 июля 2018

Я думаю, что ответ Ронака хорош для части имени, у меня действительно нет хорошей альтернативы, чтобы предложить там.

Для чисел я бы выбрал «числа и дефисы со словом границы на любом конце», т.е.

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("-")

Таким образом, вы не заблокированы в фиксированном формате для числа дефисов, которые появляются в числе (мое рекомендуемое регулярное выражение допускает любое число).

0 голосов
/ 04 июля 2018

Если вы (как и я) предпочитаете использовать 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"
0 голосов
/ 04 июля 2018

Не эксперт по регулярным выражениям, однако с пакетом 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
...