R:当电子邮件有多个域名后缀时,如何将电子邮件拆分成多个部分?
R: How do I split an email into parts when the emails have multiple domain endings?
我正在尝试分析存储在数据框 (data$Email.Address) 中的电子邮件列表,我想首先将电子邮件分成几部分,这样 example1@gmail.com、example2@outlook.org 和 example3@comcast.net 就这样结束了:
email firstpart secondpart thirdpart
1 example1@gmail.com example1 gmail com
2 example2@outlook.org example2 outlook org
3 example3@comcast.net example3 comcast net
然而,使用我当前的代码,我无法匹配所有字符串 — 因为有些
包括像 (some-url.com) 或 (us.army.mil) 这样的域。这意味着 example4@us.army.mil 显示为:
email firstpart secondpart thirdpart
4 example4@us.army.mil example4 us army
我的目标是阅读“some-url”或“us.army”作为第二部分,“com”和“mil”作为第三部分,这样就显示出来了像这样:
email firstpart secondpart thirdpart
4 example4@us.army.mil example4 us.army mil
这是我的代码:
library(tidyverse)
library(dplyr)
library(stringr)
library(rebus)
email_pattern <- capture(one_or_more(WRD)) %R%
"@" %R% capture(one_or_more(x = WRD)) %R%
DOT %R% capture(one_or_more(WRD))
#Split the emails into parts based on the pattern
email_parts <- str_match(data$Email.Address, pattern = email_pattern)
如何更改代码以便可以读取所有域?谢谢!
使用 stringi
和 data.table
的 tstrsplit()
:
library(stringi)
library(data.table)
df[paste0("part", 1:3)] <-
tstrsplit(stri_replace_last(df$email, fixed = ".", "@"), split = "@")
email part1 part2 part3
1 example1@gmail.com example1 gmail com
2 example2@outlook.org example2 outlook org
3 example3@comcast.net example3 comcast net
4 example4@us.army.mil example4 us.army mil
可复现数据(下次请自行提供):
df <- data.frame(
email = c(
"example1@gmail.com", "example2@outlook.org", "example3@comcast.net", "example4@us.army.mil"
)
)
您还可以将正则表达式捕获组与 tidyr::extract()
结合使用。
library(tidyr)
df %>%
extract(email, c("firstpart", "secondpart", "thirdpart"),
"([A-Za-z0-9_.]+)@([a-z.]+)\.([a-z]+)$", remove = FALSE)
email firstpart secondpart thirdpart
1 example1@gmail.com example1 gmail com
2 example2@outlook.org example2 outlook org
3 example3@comcast.net example3 comcast net
4 example4@us.army.mil example4 us.army mil
这是分组的细目 -- 用括号表示。
第一个 ([A-Za-z0-9_.]+)
连续捕获包含 @
之前的那些字符的所有内容。在这里您需要明确说明可以包含哪些字符。您也可以在这里使用 (.+?)
或 ([[:print:]]?)
,但我更喜欢明确。
第二个 ([a-z.]+)
捕获电子邮件地址中最后一个句点之前的所有小写字母和句点(由括号中的 \.
表示)。
最后一个 ([a-z]+)$
捕获所有小写字母,直到字符串结束。
这是使用 sindri_baldur 的示例数据的基础 R 解决方案:
df <- data.frame(email = c("example1@gmail.com", "example2@outlook.org", "example3@comcast.net", "example4@us.army.mil"))
df$firstpart <- sapply(strsplit(df$email, "@"), function (x) {
x[1]
})
df$secondpart <- strsplit(sapply(strsplit(df$email, "@"), function (x) {
x[2]
}), "[.][[:alpha:]]+$")
df$thirdpart <- sapply(seq_len(nrow(df)), function (x) {
gsub(paste0(df$firstpart[x], "@", df$secondpart[x], "."), "", df$email[x])
})
df
# email firstpart secondpart thirdpart
# 1 example1@gmail.com example1 gmail com
# 2 example2@outlook.org example2 outlook org
# 3 example3@comcast.net example3 comcast net
# 4 example4@us.army.mil example4 us.army mil
我看到你找到了一些有效的答案,但我想我会把它带回你原来的 dplyr
和 tidyr
工作流程。我认为您缺少的关键正则表达式是 "\.(?=[^.]+$)"
(抓住最后一段之后的内容)。
由于我迟到了,我在您的播放数据框中添加了第五个异想天开的条目...
library(dplyr)
library(tidyr)
df <- data.frame(
email = c(
"example1@gmail.com",
"example2@outlook.org",
"example3@comcast.net",
"example4@us.army.mil",
"example5@us.paratrooper.fort-benning.army.mil"
)
)
df %>%
separate(email, "@", into = c("userid", "domain")) %>%
separate(
col = domain,
into = c("secondpart", "thirdpart"),
sep = "\.(?=[^.]+$)")
#> userid secondpart thirdpart
#> 1 example1 gmail com
#> 2 example2 outlook org
#> 3 example3 comcast net
#> 4 example4 us.army mil
#> 5 example5 us.paratrooper.fort-benning.army mil
我正在尝试分析存储在数据框 (data$Email.Address) 中的电子邮件列表,我想首先将电子邮件分成几部分,这样 example1@gmail.com、example2@outlook.org 和 example3@comcast.net 就这样结束了:
email firstpart secondpart thirdpart
1 example1@gmail.com example1 gmail com
2 example2@outlook.org example2 outlook org
3 example3@comcast.net example3 comcast net
然而,使用我当前的代码,我无法匹配所有字符串 — 因为有些 包括像 (some-url.com) 或 (us.army.mil) 这样的域。这意味着 example4@us.army.mil 显示为:
email firstpart secondpart thirdpart
4 example4@us.army.mil example4 us army
我的目标是阅读“some-url”或“us.army”作为第二部分,“com”和“mil”作为第三部分,这样就显示出来了像这样:
email firstpart secondpart thirdpart
4 example4@us.army.mil example4 us.army mil
这是我的代码:
library(tidyverse)
library(dplyr)
library(stringr)
library(rebus)
email_pattern <- capture(one_or_more(WRD)) %R%
"@" %R% capture(one_or_more(x = WRD)) %R%
DOT %R% capture(one_or_more(WRD))
#Split the emails into parts based on the pattern
email_parts <- str_match(data$Email.Address, pattern = email_pattern)
如何更改代码以便可以读取所有域?谢谢!
使用 stringi
和 data.table
的 tstrsplit()
:
library(stringi)
library(data.table)
df[paste0("part", 1:3)] <-
tstrsplit(stri_replace_last(df$email, fixed = ".", "@"), split = "@")
email part1 part2 part3
1 example1@gmail.com example1 gmail com
2 example2@outlook.org example2 outlook org
3 example3@comcast.net example3 comcast net
4 example4@us.army.mil example4 us.army mil
可复现数据(下次请自行提供):
df <- data.frame(
email = c(
"example1@gmail.com", "example2@outlook.org", "example3@comcast.net", "example4@us.army.mil"
)
)
您还可以将正则表达式捕获组与 tidyr::extract()
结合使用。
library(tidyr)
df %>%
extract(email, c("firstpart", "secondpart", "thirdpart"),
"([A-Za-z0-9_.]+)@([a-z.]+)\.([a-z]+)$", remove = FALSE)
email firstpart secondpart thirdpart
1 example1@gmail.com example1 gmail com
2 example2@outlook.org example2 outlook org
3 example3@comcast.net example3 comcast net
4 example4@us.army.mil example4 us.army mil
这是分组的细目 -- 用括号表示。
第一个 ([A-Za-z0-9_.]+)
连续捕获包含 @
之前的那些字符的所有内容。在这里您需要明确说明可以包含哪些字符。您也可以在这里使用 (.+?)
或 ([[:print:]]?)
,但我更喜欢明确。
第二个 ([a-z.]+)
捕获电子邮件地址中最后一个句点之前的所有小写字母和句点(由括号中的 \.
表示)。
最后一个 ([a-z]+)$
捕获所有小写字母,直到字符串结束。
这是使用 sindri_baldur 的示例数据的基础 R 解决方案:
df <- data.frame(email = c("example1@gmail.com", "example2@outlook.org", "example3@comcast.net", "example4@us.army.mil"))
df$firstpart <- sapply(strsplit(df$email, "@"), function (x) {
x[1]
})
df$secondpart <- strsplit(sapply(strsplit(df$email, "@"), function (x) {
x[2]
}), "[.][[:alpha:]]+$")
df$thirdpart <- sapply(seq_len(nrow(df)), function (x) {
gsub(paste0(df$firstpart[x], "@", df$secondpart[x], "."), "", df$email[x])
})
df
# email firstpart secondpart thirdpart
# 1 example1@gmail.com example1 gmail com
# 2 example2@outlook.org example2 outlook org
# 3 example3@comcast.net example3 comcast net
# 4 example4@us.army.mil example4 us.army mil
我看到你找到了一些有效的答案,但我想我会把它带回你原来的 dplyr
和 tidyr
工作流程。我认为您缺少的关键正则表达式是 "\.(?=[^.]+$)"
(抓住最后一段之后的内容)。
由于我迟到了,我在您的播放数据框中添加了第五个异想天开的条目...
library(dplyr)
library(tidyr)
df <- data.frame(
email = c(
"example1@gmail.com",
"example2@outlook.org",
"example3@comcast.net",
"example4@us.army.mil",
"example5@us.paratrooper.fort-benning.army.mil"
)
)
df %>%
separate(email, "@", into = c("userid", "domain")) %>%
separate(
col = domain,
into = c("secondpart", "thirdpart"),
sep = "\.(?=[^.]+$)")
#> userid secondpart thirdpart
#> 1 example1 gmail com
#> 2 example2 outlook org
#> 3 example3 comcast net
#> 4 example4 us.army mil
#> 5 example5 us.paratrooper.fort-benning.army mil