\\b
表示单词边界。我不明白为什么这个运算符会根据后面的字符而产生不同的效果。示例:
test1 <- 'aland islands'
test2 <- 'åland islands'
regex1 <- "[å|a]land islands"
regex2 <- "\\b[å|a]land islands"
grepl(regex1, test1, perl = TRUE)
[1] TRUE
grepl(regex2, test1, perl = TRUE)
[1] TRUE
grepl(regex1, test2, perl = TRUE)
[1] TRUE
grepl(regex2, test2, perl = TRUE)
[1] FALSE
这似乎仅在perl = TRUE
时出现问题:
grepl(regex1, test2, perl = FALSE)
[1] TRUE
grepl(regex2, test2, perl = FALSE)
[1] TRUE
不幸的是,在我的应用程序中,我绝对需要保留perl=TRUE
。
答案 0 :(得分:4)
这是R的regex子系统中的(已知)故障,与输入的字符编码和系统区域设置/内置属性有关。
grep上的R文档指出(已突出显示):
gsub和gregexpr的POSIX 1003.2模式无法正常工作 具有重复的单词边界(例如pattern =“ \ b”)。使用perl = TRUE 对于此类匹配(,但对于非ASCII可能无法正常工作 输入,因为“单词”的含义取决于系统)。
这里仅提及gsub
和grepexpr
,grepl
似乎也受到影响。
PERL=FALSE
。使用*UCP
标志(Unicode模式| Unicode字符属性)使用PCRE(reference)正则表达式,它会更改匹配行为,因此Unicode字母数字不被视为单词边界:
代码示例:
options(encoding = "UTF-8")
test1 <- 'aland islands'
test2 <- 'åland islands'
regex1 <- "[å|a]land islands"
regex2 <- "(*UCP)\\b[å|a]land islands"
grepl(regex1, test2, perl = TRUE)
#[1] TRUE
grepl(regex2, test2, perl = TRUE)
#[1] TRUE
grepl(regex1, test2, perl = TRUE)
#[1] TRUE
grepl(regex2, test2, perl = TRUE)
#[1] TRUE
grepl(regex1, test2, perl = FALSE)
#[1] TRUE
grepl(regex2, test2, perl = FALSE)
#[1] FALSE
注意:
将TRE与(* UCP)标志一起使用的第六次测试未通过grepl(regex2, test2, perl = FALSE)
如果未在R中安装对PCRE的Unicode支持,则*UCP
标志不起作用(在some environments中可能是这种情况,例如某些最小的Cloud / Docker安装)。
真正令人讨厌的是R的行为在各个平台上是不一致的:
在这些在线R环境中测试原始代码:
只有测试案例4为FALSE:gepl(regex2, test2, perl = TRUE)
(在Linux上运行R 3.3 / 3.4吗?)
测试用例4和6为FALSE (在Linux上运行R 3.3-3.5吗?)
更多读数: