stringr::str_starts 在不应该返回 TRUE 时返回 TRUE

Bra*_*don 4 r stringr

我试图检测字符串是否以提供的字符串开头(用 | 分隔)

name = "KKSWAP"
stringr::str_starts(name, "RTT|SWAP")
Run Code Online (Sandbox Code Playgroud)

返回 TRUE,但是

str_starts(name, "SWAP|RTT")
Run Code Online (Sandbox Code Playgroud)

返回假

这种行为似乎是错误的,因为 KKSWAP 不是以“RTT”或“SWAP”开头。我希望在上述两种情况下这都是错误的。

Sal*_*lix 6

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

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)
        })
}
Run Code Online (Sandbox Code Playgroud)

您可以看到,它将“^”粘贴在模式前面,因此在您的示例中,它会查找“^RR|SWAP”并找到“SWAP”。

如果你想查看多个模式,你应该使用向量:

name <- "KKSWAP"
stringr::str_starts(name, c("RTT","SWAP"))
# [1] FALSE FALSE
Run Code Online (Sandbox Code Playgroud)

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

name <- "KKSWAP"
stringr::str_starts(name, c("RTT","SWAP"))
# [1] FALSE
Run Code Online (Sandbox Code Playgroud)

的优点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
Run Code Online (Sandbox Code Playgroud)