【问题标题】:How can I remove repeated characters in a string with R?如何使用 R 删除字符串中的重复字符?
【发布时间】:2012-06-22 21:56:53
【问题描述】:

我想用R 实现一个函数,它可以删除字符串中的重复字符。例如,假设我的函数名为removeRS,那么它应该以这种方式工作:

  removeRS('Buenaaaaaaaaa Suerrrrte')
  Buena Suerte
  removeRS('Hoy estoy tristeeeeeee')
  Hoy estoy triste

我的函数将与用西班牙语编写的字符串一起使用,因此查找具有三个以上连续元音的单词并不常见(或至少正确)。不用担心他们背后可能存在的情绪。尽管如此,有些单词可以有两个连续的辅音(尤其是 ll 和 rr),但我们可以从函数中跳过它。

所以,总而言之,这个函数应该用那个字母替换连续出现至少 3 次的字母。在上述示例之一中,aaaaaaaaa 被替换为 a

您能给我任何提示以使用R 执行此任务吗?

【问题讨论】:

  • “此任务”当前未明确指定。尾随的重复元音可能需要以不同的方式处理,但从描述中不清楚。

标签: string r


【解决方案1】:

我没有仔细考虑这一点,但这是我在正则表达式中使用引用的快速解决方案:

gsub('([[:alpha:]])\\1+', '\\1', 'Buenaaaaaaaaa Suerrrrte')
# [1] "Buena Suerte"

()先捕获一个字母,\\1指那个字母,+表示匹配一次或多次;将所有这些部分放在一起,我们可以匹配一个字母两次或多次。

要包含字母数字以外的其他字符,请将[[:alpha:]] 替换为匹配您希望包含的任何内容的正则表达式。

【讨论】:

  • 谢谢,如果你想从中排除一些字母呢?例如,排除字母 L 和 R。
  • [:alpha:] 表示a-zA-Z;如果你想具体一点,你可以说,例如[a-zA-KM-QS-Z] 删除大写 L 和 R;见?regexp
  • 这是一个使用 perl 风格的零宽度前瞻正则表达式的变体:gsub("([[:alpha:]])(?=\\1)", "", s, perl = TRUE)。它匹配所有字母字符中除最后一个之外的所有字符。
  • @G.Grothendieck 将[[:alpha:]]perl=True 一起工作吗?这不是有效的 PCRE 语法。
  • @G.Grothendieck 对于这个特定的任务,你的版本要慢得多,没有真正的收获。不过,作为旁注很好。
【解决方案2】:

我认为您应该注意问题描述中的歧义。这是第一次尝试,但它显然不能以您希望的方式与“祝你好运”一起工作:

removeRS <- function(str) paste(rle(strsplit(str, "")[[1]])$values, collapse="")
removeRS('Buenaaaaaaaaa Suerrrrte')
#[1] "Buena Suerte"

【讨论】:

  • 感谢您的回答@DWin。 “祝你好运”的例子根本不打扰我,我接受并为模棱两可道歉。从这个意义上说,英语中的事情不像西班牙语那样有效。我尝试了您的解决方案,它可以按我的意愿工作。顺便说一句,我已经编辑了这个问题以使其更清楚。
【解决方案3】:

由于您要替换出现至少 3 次的字母,因此这是我的解决方案:

gsub("([[:alpha:]])\\1{2,}", "\\1", "Buennaaaa Suerrrtee")
#[1] "Buenna Suertee"

如您所见,4“a”已缩减为仅 1 a,3 r 已缩减为 1 r,但 2 n 和 2 e 未更改。 如上所述,您可以将[[:alpha:]] 替换为[a-zA-KM-Z] 或类似的任意组合,如果您希望代码仅影响y 和问。

gsub("([a|e])\\1{2,}", "\\1", "Buennaaaa Suerrrtee")
# [1] "Buenna Suerrrtee"
# triple r are not affected and there are no triple e.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-30
    • 2015-06-07
    • 1970-01-01
    • 1970-01-01
    • 2013-11-12
    相关资源
    最近更新 更多