如何使用R删除字符串中的重复字符?

23

我希望使用 R 实现一个函数,可以去除字符串中的重复字符。例如,假设我的函数名为 removeRS,则应按照以下方式工作:

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

我的函数将用于处理西班牙语字符串,因此在找到连续三个元音字母的单词时并不常见(或者至少不正确)。不必担心这些单词可能包含的情感。然而,有些单词可以有两个连续的辅音字母(尤其是ll和rr),但我们可以从函数中跳过它们。

所以,总结一下,该函数应该使用该字母替换出现至少三次的连续字母。在上面的示例中,aaaaaaaaa被替换为a

你能给我一些提示来使用R完成这个任务吗?


此任务目前尚未明确定义。可能需要对重复的尾随元音采取不同的处理方式,但从描述中无法清楚了解。 - IRTFM
3个回答

38

我并没有认真地考虑这个问题,但这是我的快速解决方案,使用正则表达式中的引用:

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

()首先匹配一个字母,\\1引用之前匹配的那个字母,+表示匹配一次或多次;将这些组合起来,我们可以匹配两个或更多个字母。

如果要包括除字母数字以外的其他字符,请使用与您希望包括的内容匹配的正则表达式替换[[:alpha:]]


1
谢谢,如果你想从中排除一些字母怎么办?例如,排除字母L和R。 - nhern121
[:alpha:] 表示 a-zA-Z;如果你想更具体一些,可以使用 [a-zA-KM-QS-Z] 来去除大写字母 L 和 R;请参考 ?regexp - Yihui Xie
1
这里是使用 Perl 风格的零宽度前瞻正则表达式的变体:gsub("([[:alpha:]])(?=\\1)", "", s, perl = TRUE)。它匹配任何字母字符连续出现中除了最后一个以外的所有字符。 - G. Grothendieck
@G.Grothendieck,如果 perl=True[[:alpha:]] 能用吗?这不是有效的 PCRE 语法。 - ivan_pozdeev
@G.Grothendieck 对于这个特定的任务,你的版本速度较慢,没有真正的收益。不过,作为一个附注还是很好的。 - ivan_pozdeev

7

我认为你需要注意问题描述中的歧义。这是一个初步的尝试,但显然不能按照你所期望的方式与“Good Luck”配合使用:

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

感谢您的回答@DWin。 "Good Luck" 的示例对我完全没有影响,我接受并为歧义道歉。在这方面,英语与西班牙语的表达方式不同。我尝试了您的解决方案,它按照我所期望的工作。顺便说一下,我已经编辑问题,以使其更清晰明了。 - nhern121

2

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

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

正如您所看到的,4个“a”已经被减少到只有1个,“r”的3个也被减少到了1个,但是2个“n”和2个“e”没有改变。 如上所述,您可以将[[:alpha:]]替换为任何组合的[a-zA-KM-Z]或类似的内容,甚至可以在方括号[y|Q]内使用“或”运算符|,如果您希望代码仅影响y和Q的重复。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接