这里的要点是,在某些情况下,会存在包含较短重复子串的重复子串。因此,为了匹配更长的,你可以使用
\n\n(\\b.+\\b)\\1\\b\nRun Code Online (Sandbox Code Playgroud)\n\n(请参阅正则表达式演示)对于那些要查找较短子字符串的人,我会依赖惰性点匹配:
\n\n(\\b.+?\\b)\\1\\b\nRun Code Online (Sandbox Code Playgroud)\n\n请参阅此正则表达式演示。替换字符串将是\\1对首先与分组结构匹配的捕获部分的反向引用(...)。
您需要一个 PCRE 正则表达式才能使其工作,因为有记录的与多个单词边界匹配的问题gsub(因此,添加perl=T参数)。
\n\n\ngsub 和 gregexpr 的 POSIX 1003.2 模式对于重复的字边界(例如 )无法正常工作
\npattern = "\\b"。用于perl = TRUE此类匹配(但对于非 ASCII 输入可能无法按预期工作,因为 \xe2\x80\x98word\xe2\x80\x99 的含义取决于系统)。
请注意,如果重复的子字符串可以跨越多行,则可以(?s)在模式开头使用带有 DOTALL 修饰符的 PCRE 正则表达式(以便 a.也可以匹配换行符)。
所以,R 代码看起来像
\n\ngsub("(?s)(\\\\b.+\\\\b)\\\\1\\\\b", "\\\\1", s, perl=T)\nRun Code Online (Sandbox Code Playgroud)\n\n或者
\n\ngsub("(?s)(\\\\b.+?\\\\b)\\\\1\\\\b", "\\\\1", s, perl=T)\nRun Code Online (Sandbox Code Playgroud)\n\n请参阅IDEONE 演示:
\n\ntext <- "are blue and then and then more and then and then more very bright"\ngsub("(?s)(\\\\b.+?\\\\b)\\\\1\\\\b", "\\\\1", text, perl=T) ## shorter repeated substrings\n## [1] "are blue and then more and then more very bright"\ngsub("(?s)(\\\\b.+\\\\b)\\\\1\\\\b", "\\\\1", text, perl=T) ## longer repeated substrings\n## [1] "are blue and then and then more very bright"\nRun Code Online (Sandbox Code Playgroud)\n