我正在努力让
strsplit
和 stri_extract_all_regex
始终如一地工作。按 strsplit 拆分是所需的行为(实际上,我有一长串由代码动态生成的替代匹配)。
例如
strsplit("1234567","(23)|(234)")
[[1]]
[1] "1" "567"
对
stri_extract_all_regex("1234567","(23)|(234)")
[[1]]
[1] "23"
提取所需的输出是
[[1]]
[1] "234"
这取决于所使用的正则表达式引擎。 Base R 默认使用扩展正则表达式 (ERE),或Perl 兼容正则表达式 (PCRE)。相反,“stringi”[文档] 指出了这一点:
提供对 ICU 中实现的正则表达式引擎的访问,该引擎的灵感来自于 JDK 1.4 中的 Java
util.regex
我们可以看到它的实际效果:
library(stringi)
x <- "1234567"
pattern <- "(23)|(234)"
# Base R (ERE) engine
regmatches(x, gregexpr(pattern, x)) |> unlist()
# [1] "234"
# Base R (PCRE) engine
regmatches(x, gregexpr(pattern, x, perl = TRUE)) |> unlist()
# [1] "23"
stri_extract_all_regex(x, pattern) |> unlist()
# [1] "23"
但是,如果我们改变顺序
pattern <- "(234)|(23)"
,它们都会返回234
。
动态生成模式后,您可以编写一个函数来按最长的优先顺序对其模式进行排序。
switch_pattern_order <- function(pattern){
pattern_split <- unlist(strsplit(pattern, "|", fixed = TRUE))
pattern_sorted <- pattern_split[rev(order(nchar(pattern_split)))]
new_pattern <- paste(pattern_sorted, collapse = "|")
new_pattern
}
pattern <- switch_pattern_order(pattern) # "(234)|(23)"
regmatches(x, gregexpr(pattern, x)) |> unlist()
# [1] "234"
regmatches(x, gregexpr(pattern, x, perl = TRUE)) |> unlist()
# [1] "234"
stri_extract_all_regex(x, pattern) |> unlist()
# [1] "234"