为什么这个行尾(\\ b)在stringr/ICU和Perl中不被识别为字边界

Ren*_*rop 6 regex pcre r stringr

使用stringr我试图检测字符串末尾的符号,如下所示:

str_detect("my text €", "€\\b") # FALSE
Run Code Online (Sandbox Code Playgroud)

为什么这不起作用?它在以下情况下工作:

str_detect("my text a", "a\\b") # TRUE - letter instead of €
grepl("€\\b", "2009in €") # TRUE - base R solution
Run Code Online (Sandbox Code Playgroud)

但它在perl模式下也失败了:

grepl("€\\b", "2009in €", perl=TRUE) # FALSE
Run Code Online (Sandbox Code Playgroud)

那么€\\b-regex有什么问题呢?正则表达式€$适用于所有情况......

Wik*_*żew 4

当您使用不带 的基本 R 正则表达式函数时perl=TRUE,将使用TRE 正则表达式风格。

看起来 TRE 单词边界:

  • 当非单词字符与字符串位置的末尾匹配之后使用时,并且
  • 当在非单词字符之前使用时,它与字符串位置的开头匹配。

请参阅 R 测试:

> gsub("\\b\\)", "HERE", ") 2009in )")
[1] "HERE 2009in )"
> gsub("\\)\\b", "HERE", ") 2009in )")
[1] ") 2009in HERE"
> 
Run Code Online (Sandbox Code Playgroud)

这不是PCRE 和 ICU 正则表达式风格中单词边界的常见行为,其中非单词字符之前的单词边界仅在该字符前面带有单词字符时匹配,不包括字符串位置的开头(以及在非单词字符需要单词字符出现在单词边界之后):

三个不同的位置符合单词边界:

- 在字符串中的第一个字符之前(如果第一个字符是单词字符)。
- 在字符串中的最后一个字符之后,如果最后一个字符是单词字符。
- 字符串中的两个字符之间,其中一个是单词字符,另一个不是单词字符。