【问题标题】:Regular Expression For Consecutive Duplicate Bigrams连续重复二元组的正则表达式
【发布时间】:2016-04-20 15:15:08
【问题描述】:

我的问题是早先question 的直接扩展,关于检测字符串中的连续单词(unigrams)。

在上一个问题中,

是相关的

可以通过这个正则表达式检测到:\b(\w+)\s+\1\b

在这里,我想检测连续的二元组(单词对):

是蓝色的然后很亮

理想情况下,我也想知道如何将检测到的模式(重复)替换为单个元素,从而得到:

是蓝色的,然后很亮

(对于这个应用程序,如果重要,我在 R 中使用gsub

【问题讨论】:

  • 这里可能存在边缘情况...您的确切标准是什么?试试(\b.+\b)\1\bgsub("(\\b.+\\b)\\1\\b", "\\1", s, perl=T).
  • 感谢您对我的问题感兴趣。 edge cases 是什么意思?
  • 您提出的解决方案似乎效果很好...edge cases 是指在某些情况下它可能会出现意外行为吗?
  • @WiktorStribiżew 您的解决方案将不起作用in all cases
  • @WiktorStribiżew Still does not work...

标签: regex r gsub


【解决方案1】:

这里的重点是,在某些情况下,会出现包含较短重复子串的重复子串。所以,为了匹配更长的,你会使用

(\b.+\b)\1\b

(参见regex demo)对于那些找到较短子字符串的人,我会依赖惰性点匹配

(\b.+?\b)\1\b

this regex demo。替换字符串将是 \1 - 对捕获部分的反向引用首先与分组构造 (...) 匹配。

您需要一个 PCRE 正则表达式才能使其工作,因为在将多个单词边界与 gsub 匹配方面存在记录问题(因此,添加 perl=T 参数)。

gsub 和 gregexpr 的 POSIX 1003.2 模式无法正确处理重复的单词边界(例如,pattern = "\b")。使用 perl = TRUE 进行此类匹配(但对于非 ASCII 输入,这可能无法按预期工作,因为“单词”的含义取决于系统)。

请注意,如果您的重复子字符串可以跨越多行,您可以在模式的开头使用带有 DOTALL 修饰符 (?s) 的 PCRE 正则表达式(这样. 也可以匹配换行符)。

所以,R 代码看起来像

gsub("(?s)(\\b.+\\b)\\1\\b", "\\1", s, perl=T)

gsub("(?s)(\\b.+?\\b)\\1\\b", "\\1", s, perl=T)

IDEONE demo

text <- "are blue and then and then more and then and then more very bright"
gsub("(?s)(\\b.+?\\b)\\1\\b", "\\1", text, perl=T) ## shorter repeated substrings
## [1] "are blue and then more and then more very bright"
gsub("(?s)(\\b.+\\b)\\1\\b", "\\1", text, perl=T) ## longer repeated substrings
## [1] "are blue and then and then more very bright"

【讨论】:

    【解决方案2】:

    试试下面的正则表达式:

    (\b.+?\b)\1\b
    

    RegEx 将捕获一个单词边界,然后是数据,然后是另一个单词边界。 \1 将引用捕获的内容,然后再次选择它。然后它将检查末尾的单词边界以防止选择a andz zoo

    至于替换,使用\1。这将包含来自 1st Capture Group 的数据(二元组的第一部分),第一部分将用于替换整个数据。

    Live Demo on Regex101

    【讨论】:

    • @WiktorStribiżew 你是第一个通过你的 cmets 回答的人。当前的答案与您提出的几乎完全相同(我能看到的唯一区别是最后的\b),所以如果您发布答案,我会接受它,因为您是第一个
    • @WiktorStribiżew 实际上不,您在 cmets 中提出的内容与当前答案之间甚至没有区别。因此,如果您发布答案,我肯定会接受它
    • 这很尴尬。我从来没有遇到过这种情况。
    • 好的,我会写一个全面的R相关答案。这个不用删。
    • 太好了,我认为这解决了它
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-26
    • 1970-01-01
    • 1970-01-01
    • 2010-12-31
    相关资源
    最近更新 更多