首页 > 解决方案 > 使用 grepl 匹配特定文本,但不匹配该文本的子字符串

问题描述

我正在尝试使用匹配特定文本,grepl()同时确保没有较短的子字符串也返回匹配项。

例如,我想grepl('liverpool', 'club_futbol_liverpool_fc')退货TRUE,但我不想grepl('pool', 'club_futbol_liverpool_fc')退货TRUE。在这种情况下,我不能使用^and $,因为我要匹配的文本前后都有字符。写作grepl('.*^liverpool$.*', 'club_futbol_liverpool_fc')也无济于事,我只是意识到这与仅使用^and相同$

有没有办法做到这一点?

我应该补充一点,最终目标是grepl()在 for 循环中使用此函数来匹配数据框中的观察结果。不幸的是,liverpool不会总是被下划线包围,尽管我相信总会有至少一个下划线,无论是 before 还是 after liverpool

标签: rregex

解决方案


您可以使用

grepl('(?:\b|_)pool(?:\b|_)', x)
grepl('(?<![^\\W_])pool(?![^\\W_])', x, perl = TRUE)

请参阅正则表达式演示 #1正则表达式演示 #2

上面的模式意味着

  • (?:\b|_)- 字边界或_消耗的字符
  • (?<![^\W_])- 字符串中的一个位置,其前面没有紧跟字母或数字 ([^\W_]匹配除非单词 char 和下划线以外的任何字符,即匹配除下划线之外的任何单词 char,有效地匹配字母或数字)
  • pool- 一个字
  • (?![^\W_])- 字符串中不紧跟字母或数字的位置。

环顾四周,(?<!...)并且(?!...)是非消耗模式,并且默认的 TRE 正则表达式库不支持它们,因此您需要使用perl=TRUEPCRE 正则表达式库来解析表达式。


推荐阅读