R正则表达式匹配/省略几次重复

时间:2017-04-30 20:56:24

标签: r regex

我正在使用反向引用来消除变量名称向量中的意外重复。我遇到的第一种情况中的名称有重复的模式,如

-c

重复总是用下划线分开,只有一个重复消除。它们总是从文本的开头开始。在检查了正则表达式食谱,2ed后,我得到了一个有效的答案:

x <- c("gender_gender-1", "county_county-2", "country_country-1997",
       "country_country-1993")

我担心未来的案例可能会有破折号或空格作为分隔符,所以我想稍微概括一下匹配。我也得到了解决方案。

> gsub("^(.*?)_\\1", "\\1", x)
[1] "gender-1"     "county-2"     "country-1997" "country-1993"
到目前为止,总胜利。

现在,如果在某些情况下有三次重复,那么正确的修复是什么?在这一个中,我希望“国家 - 国家 - 国家”成为一个“国家”。

> x <- c("gender_gender-1", "county-county-2", "country country-1997",
+       "country,country-1993")
> gsub("^(.*?)[,_\ -]\\1", "\\1", x)
[1] "gender-1"     "county-2"     "country-1997" "country-1993"

我愿意用“_”替换所有的分隔符,如果这样可以更容易地删除重复的单词。

1 个答案:

答案 0 :(得分:5)

您可以量化[,_ -]\1部分:

gsub("^(.*?)(?:[,_\\s-]\\1)+", "\\1", x, perl=TRUE)

请参阅R demo

注意我也用\s替换空格以匹配任何空格(这需要perl=TRUE)。您也可以将任何空格与[:space:]匹配,然后您不需要perl=TRUE,即gsub("^(.*?)(?:[,_[:space:]-]\\1)+", "\\1", x)

<强>详情:

  • ^ - 匹配字符串的开头
  • (.*?) - 任意0个字符尽可能少到第一个......
  • (?:
    • [,_\\s-] - ,_,空格或-
    • \\1 - 与第1组中捕获的值相同
  • )+ - 1次或更多次。

如果您只想将重复部分匹配1或2次,请将+替换为{1,2}限制量词:

gsub("^(.*?)(?:[,_\\s-]\\1){1,2}", "\\1", x, perl=TRUE)