我想检查列表中的数字是否与特定格式的(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。 '
答案 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。