【问题标题】:Why does is this end of line (\\b) not recognised as word boundary in stringr/ICU and Perl为什么行尾 (\\b) 在 stringr/ICU 和 Perl 中不被识别为单词边界
【发布时间】:2017-05-01 16:38:19
【问题描述】:

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

str_detect("my text €", "€\\b") # FALSE

为什么这不起作用?它适用于以下情况:

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

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

grepl("€\\b", "2009in €", perl=TRUE) # FALSE

那么€\\b-regex 有什么问题?正则表达式€$ 在所有情况下都有效...

【问题讨论】:

    标签: r regex pcre stringr


    【解决方案1】:
    \b
    

    等价于

    (?:(?<!\w)(?=\w)|(?<=\w)(?!\w))
    

    也就是说匹配

    • 在单词 char 和非单词 char 之间,
    • 在单词 char 和字符串开头之间,并且
    • 在单词 char 和字符串结尾之间。

    是一个符号,而符号不是单词字符。

    $ uniprops €
    U+20AC <€> \N{EURO SIGN}
        \pS \p{Sc}
        All Any Assigned Common Zyyy Currency_Symbol Sc Currency_Symbols S Gr_Base Grapheme_Base Graph X_POSIX_Graph GrBase Print X_POSIX_Print Symbol Unicode
    

    如果您的语言支持后视和前瞻,您可以使用以下方法来找到空格和非空格之间的边界(将开头和结尾视为空格)。

    (?:(?<!\S)(?=\S)|(?<=\S)(?!\S))
    

    【讨论】:

    • (?:(?&lt;!\s)(?=\s)|(?&lt;=\s)(?!\s)) 不受 TRE 正则表达式支持,因为它不支持环视。至于在字符串末尾匹配 € 符号$ 就可以了。
    • @Wiktor Stribiżew,谢谢。我不想完全删除该模式,因为它可能对其他人有用,但我改写了该声明以说明它对 OP 没有用处。
    • 是的,它将与 ICU(stringr 函数)和perl=TRUE "powered" base R 一起使用。
    • 啊,我看到它使用不同的引擎匹配,我没有解释。也就是说,我确实提供了其他答案中没有的两个重要信息。
    【解决方案2】:

    当您使用没有perl=TRUE 的基本R 正则表达式函数时,将使用TRE regex flavor

    看来是TRE字边界:

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

    查看 R 测试:

    > gsub("\\b\\)", "HERE", ") 2009in )")
    [1] "HERE 2009in )"
    > gsub("\\)\\b", "HERE", ") 2009in )")
    [1] ") 2009in HERE"
    > 
    

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

    有资格作为单词边界的三个不同位置:

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

    【讨论】:

      猜你喜欢
      • 2023-01-02
      • 1970-01-01
      • 2021-10-14
      • 1970-01-01
      • 1970-01-01
      • 2019-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多