stringr::str_starts returns 不应该为真

stringr::str_starts returns TRUE when it shouldn't

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

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

returns 正确,但是

str_starts(name, "SWAP|RTT")

returns 错误

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

我不熟悉 stringr 版本,但基本 R 版本 startsWith returns 您想要的结果。如果你不必使用 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)

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

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