r语言 - stringr::str_starts 在不应该返回 TRUE 时返回 TRUE



我正在尝试检测字符串是否以提供的字符串中的任何一个开头(用|分隔(

name = "KKSWAP"
stringr::str_starts(name, "RTT|SWAP")

返回TRUE,但

str_starts(name, "SWAP|RTT")

返回FALSE

这种行为似乎是错误的,因为KKSWAP并不是以";RTT";或";SWAP";。在上述两种情况下,我都认为这是错误的。

原因可以在函数的代码中找到:

function (string, pattern, negate = FALSE) 
{
switch(type(pattern), empty = , bound = stop("boundary() patterns are not supported."), 
fixed = stri_startswith_fixed(string, pattern, negate = negate, 
opts_fixed = opts(pattern)), coll = stri_startswith_coll(string, 
pattern, negate = negate, opts_collator = opts(pattern)), 
regex = {
pattern2 <- paste0("^", pattern)
attributes(pattern2) <- attributes(pattern)
str_detect(string, pattern2, negate)
})
}

您可以看到,它将"^"粘贴在parttern前面,因此在您的示例中,它查找"^RR|SWAP"并找到"SWAP"。

如果你想观察不止一种模式,你应该使用一个向量:

name <- "KKSWAP"
stringr::str_starts(name, c("RTT","SWAP"))
# [1] FALSE FALSE

如果你只想要一个答案,你可以结合any()

name <- "KKSWAP"
stringr::str_starts(name, c("RTT","SWAP"))
# [1] FALSE

stringr::str_starts()的优点是模式参数的矢量化,但如果您不需要它,grepl('^RTT|^SWAP', name)(如TTS所建议的(是一个很好的基本R替代方案。

或者,jpsmith提出的基本函数startsWith()同时提供了矢量化和|选项:

startsWith(name, c("RTT","SWAP"))
# [1] FALSE FALSE
startsWith(name, "RTT|SWAP")
# [1] FALSE

我不熟悉stringr版本,但基本R版本startsWith会返回您想要的结果。如果你不必使用stringr,这可能是一个解决方案:

startsWith(name, "RTT|SWAP")
startsWith(name, "SWAP|RTT")
startsWith(name, "KK")
# > startsWith(name, "RTT|SWAP")
# [1] FALSE
# > startsWith(name, "SWAP|RTT")
# [1] FALSE
# > startsWith(name, "KK")
# [1] TRUE

帮助文本描述str_starts:检测字符串开头或结尾是否存在模式这可能就是它表现不如预期的原因。

pattern是字符串开始或结束的模式

我们可以添加^正则表达式,使其在字符串的开头进行搜索,并获得预期的结果。

name = 'KKSWAP'
str_starts(name, '^RTT|^SWAP')

在这种情况下,我更喜欢grepl,因为它似乎不那么具有误导性。

grepl('^RTT|^SWAP', name)

最新更新