str_detect,使用特定模式验证电话号码

时间:2018-07-12 19:02:35

标签: r regex stringr

我想检查列表中的数字是否与特定格式的(nnn.nnn.nnnn)相匹配。我期望代码返回布尔值(FALSE, TRUE, FALSE, TRUE, FALSE, FALSE),但是当我希望它为TRUE时,最后一个元素返回FALSE

 library(stringr)

 numbers <- c('571-566-6666', '456.456.4566', 'apple', '222.222.2222', '222 333 
 4444', '2345.234.2345')

 str_detect(numbers, "[:digit:]{3}\\.[:digit:]{3}\\.[:digit:]{4}")

如果我使用:

str_detect(numbers, "[:digit:]{4}\\.[:digit:]{3}\\.[:digit:]{4}")

我得到(FALSE, FALSE, FALSE, FALSE, FALSE, TRUE),所以我知道精确匹配的模式有效,但是我不确定为什么当有4个数字而不是'之前的3个数字时,第一个代码块对最后一个元素返回TRUE。 '

1 个答案:

答案 0 :(得分:0)

这是因为最后一个值的末尾有“ 345.234.2345”,因此您不需要模式以匹配值开头和结尾。

尝试以下模式:

"^[:digit:]{3}\\.[:digit:]{3}\\.[:digit:]{4}$"

如果您想匹配一个可能在内部的字符串,或者匹配一个在结尾或开头以空格分隔的字符串,则可能更通用:

"(^|[ ])[:digit:]{3}\\.[:digit:]{3}\\.[:digit:]{4}([ ]|$)"

测试:

numbers <- c('571-566-6666', '456.456.4566', 'apple', '222.222.2222', '222 333 
 4444', '2345.234.2345', "interior test 456.456.4566 other", 
'456.456.4566 beginning test', "end test 456.456.4566")

 str_detect(numbers, "(^|[ ])[:digit:]{3}\\.[:digit:]{3}\\.[:digit:]{4}([ ]|$)")
#[1] FALSE  TRUE FALSE  TRUE FALSE FALSE  TRUE  TRUE  TRUE

正如Wictor所指出的那样,只要您以R模式对它进行两次转义,也可以使用边界操作符一词。

grepl("\\b[[:digit:]]{3}\\.[[:digit:]]{3}\\.[[:digit:]]{4}\\b", numbers)
[1] FALSE  TRUE FALSE  TRUE FALSE FALSE  TRUE  TRUE  TRUE

注意事项:stringr函数(如果我没记错的话,是基于stringi函数)似乎与“普通” R regex函数不同,因为它们允许使用特殊字符类而无需双括号。

  grepl("(^|[ ])[:digit:]{3}\\.[:digit:]{3}\\.[:digit:]{4}([ ]|$)", numbers)
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  grepl("(^|[ ])[[:digit:]]{3}\\.[[:digit:]]{3}\\.[[:digit:]]{4}([ ]|$)", numbers)
[1] FALSE  TRUE FALSE  TRUE FALSE FALSE  TRUE  TRUE  TRUE

显然,这是通过将“ fixed”的隐式设置设置为TRUE。