在 R 中屏蔽 phone 数字
Mask phone number in R
我的原始数据有很多个人信息,所以我在R中屏蔽了它们。示例数据和我的原始代码如下:
install.packages("stringr")
library(string)
x = c("010-1234-5678",
"John 010-8888-8888",
"Phone: 010-1111-2222",
"Peter 018.1111.3333",
"Year(2007,2019,2020)",
"Alice 01077776666")
df = data.frame(
phoneNumber = x
)
pattern1 = "\d{3}-\d{4}-\d{4}"
pattern2 = "\d{3}.\d{4}.\d{4}"
pattern3 = "\d{11}"
delPhoneList1 <- str_match_all(df, pattern1) %>% unlist
delPhoneList2 <- str_match_all(df, pattern2) %>% unlist
delPhoneList3 <- str_match_all(df, pattern3) %>% unlist
我从数据集中找到了三种类型的模式,每种结果如下:
> delPhoneList1
[1] "010-1234-5678" "010-8888-8888" "010-1111-2222"
> delPhoneList2
[1] "010-1234-5678" "010-8888-8888" "010-1111-2222" "018.1111.3333" "007,2019,2020"
> delPhoneList3
[1] "01077776666"
Pattern1 是我所在国家/地区使用破折号的典型 phone 数字类型,但有人使用逗号输入类似 pattern2 的数字。但是,pattern2 还包括 pattern1,因此它会检测其他模式,如一系列年份。这是意想不到的结果。
我的问题是如何匹配我定义的确切模式。 pattern2 包含过多的模式,例如来自 "Year(2007,2019,2020)"
的 "007,2019,2020"
。
此外,下一步是使用以下代码屏蔽号码:
for (phone in delPhoneList1) {
df$phoneNumber <- gsub(phone, "010-9999-9999", df$phoneNumber)
}
我认为该代码非常适合我,但如果您有更有效的方法,请告诉我。
谢谢。
一种模式统领一切;-)
ptn <- "\b\d{3}([-.]?)\d{4}\1\d{4}\b"
grepl(ptn, x)
# [1] TRUE TRUE TRUE TRUE FALSE TRUE
您的 pattern2
失败的原因是因为它使用 .
作为分隔符,但在正则表达式中这意味着“任何字符”。您可以使用 \.
而不是 .
并且它的表现会更好。
我在这里使用占位符:如果第一个分隔符是 -
,那么 \1
确保另一个分隔符相同。如果它是空的,那么第二个也是空的。这也让pattern3
.
的11个不间断数
\b
是单词边界,向我们保证 12 位数字 不会 匹配:
grepl(ptn, c("12345678901", "123456789012"))
# [1] TRUE FALSE
由于它有一个占位符,它往往会与 stringr::
函数有些混乱,但我们可以解决这个问题,具体取决于您的需要。
例如,如果您用相同模式的第二个实例替换占位符,它可能允许 123-4444.5555
(混合分隔符),如果这不是问题的话。
ptn2 <- "\b\d{3}[-.]?\d{4}[-.]?\d{4}\b"
unlist(str_match_all(x, ptn2))
# [1] "010-1234-5678" "010-8888-8888" "010-1111-2222" "018.1111.3333" "01077776666"
或者我们可以利用匹配的模式数(原始ptn
):
unlist(str_match(x, ptn)[,1])
# [1] "010-1234-5678" "010-8888-8888" "010-1111-2222" "018.1111.3333" NA "01077776666"
我的原始数据有很多个人信息,所以我在R中屏蔽了它们。示例数据和我的原始代码如下:
install.packages("stringr")
library(string)
x = c("010-1234-5678",
"John 010-8888-8888",
"Phone: 010-1111-2222",
"Peter 018.1111.3333",
"Year(2007,2019,2020)",
"Alice 01077776666")
df = data.frame(
phoneNumber = x
)
pattern1 = "\d{3}-\d{4}-\d{4}"
pattern2 = "\d{3}.\d{4}.\d{4}"
pattern3 = "\d{11}"
delPhoneList1 <- str_match_all(df, pattern1) %>% unlist
delPhoneList2 <- str_match_all(df, pattern2) %>% unlist
delPhoneList3 <- str_match_all(df, pattern3) %>% unlist
我从数据集中找到了三种类型的模式,每种结果如下:
> delPhoneList1
[1] "010-1234-5678" "010-8888-8888" "010-1111-2222"
> delPhoneList2
[1] "010-1234-5678" "010-8888-8888" "010-1111-2222" "018.1111.3333" "007,2019,2020"
> delPhoneList3
[1] "01077776666"
Pattern1 是我所在国家/地区使用破折号的典型 phone 数字类型,但有人使用逗号输入类似 pattern2 的数字。但是,pattern2 还包括 pattern1,因此它会检测其他模式,如一系列年份。这是意想不到的结果。
我的问题是如何匹配我定义的确切模式。 pattern2 包含过多的模式,例如来自 "Year(2007,2019,2020)"
的 "007,2019,2020"
。
此外,下一步是使用以下代码屏蔽号码:
for (phone in delPhoneList1) {
df$phoneNumber <- gsub(phone, "010-9999-9999", df$phoneNumber)
}
我认为该代码非常适合我,但如果您有更有效的方法,请告诉我。
谢谢。
一种模式统领一切;-)
ptn <- "\b\d{3}([-.]?)\d{4}\1\d{4}\b"
grepl(ptn, x)
# [1] TRUE TRUE TRUE TRUE FALSE TRUE
您的
pattern2
失败的原因是因为它使用.
作为分隔符,但在正则表达式中这意味着“任何字符”。您可以使用\.
而不是.
并且它的表现会更好。我在这里使用占位符:如果第一个分隔符是
的11个不间断数-
,那么\1
确保另一个分隔符相同。如果它是空的,那么第二个也是空的。这也让pattern3
.\b
是单词边界,向我们保证 12 位数字 不会 匹配:grepl(ptn, c("12345678901", "123456789012")) # [1] TRUE FALSE
由于它有一个占位符,它往往会与 stringr::
函数有些混乱,但我们可以解决这个问题,具体取决于您的需要。
例如,如果您用相同模式的第二个实例替换占位符,它可能允许 123-4444.5555
(混合分隔符),如果这不是问题的话。
ptn2 <- "\b\d{3}[-.]?\d{4}[-.]?\d{4}\b"
unlist(str_match_all(x, ptn2))
# [1] "010-1234-5678" "010-8888-8888" "010-1111-2222" "018.1111.3333" "01077776666"
或者我们可以利用匹配的模式数(原始ptn
):
unlist(str_match(x, ptn)[,1])
# [1] "010-1234-5678" "010-8888-8888" "010-1111-2222" "018.1111.3333" NA "01077776666"