R中的正则表达式提取子串省略了最后几个字符?

时间:2017-03-13 22:02:01

标签: r regex

我的数据框看起来像

ID              Name
1     Super novaNOVA
2           ABCDABCD
3 The ATM MachineATM
4          AlaskaULA
5      StomrsvilleST
6           HikeHIKE
...

我想将Name列中的条目保持不变,但删除所有大写字母中的最后一个字符。也就是说,我希望它看起来像

ID           Name
1      Super nova
2            ABCD
3 The ATM Machine
4          Alaska
5     Stomrsville
6            Hike
...

ABCDABCD的情况下,尽管所有的字符都是大写的,但我只有一半。因为ABCD只是重复,所以我只需要ABCD

我怎样才能在R?

中这样做

编辑:Super novaNOVA应该变为Super nova,而不是Supernova

2 个答案:

答案 0 :(得分:1)

您可以使用

x <- c("Super novaNOVA", "ABCDABCD", "The ATM MachineATM", "AlaskaULA", "StomrsvilleST", "HikeHIKE", "MooneMOONE", "ABCABC", "Laser (MD)L-MD")
sub("(?s)^(.*)(?i:\\1)$|[A-Z-]{1,4}$", "\\1", x, perl=TRUE)

请参阅online R demoonline regex demo

如果一个字符串由2个重复部分组成,则只保留1个部分,另一部分用^(.*)(?i:\\1)$删除或1到4个大写ASCII字母或-被删除。

<强>详情:

  • (?s) - DOTALL修饰符(在PCRE正则表达式中,.不会自动匹配换行符)
  • ^ - 字符串的开头
  • (.*) - 第1组捕获尽可能多的0个字符
  • (?i:\\1) - 一个修饰符组,以不区分大小写的方式匹配与第1组相同的文本
  • $ - 字符串结尾
  • | - 或
  • [A-Z-]{1,4} - 1到4个大写ASCII字母或-到...
  • $ - 字符串结束。

答案 1 :(得分:0)

因为你不确定大写单词的最小或最大数量,我建议 [A-Z] * $

x <- replicate(15, paste0(paste0(sample(letters,3), collapse = ""), paste0(sample(LETTERS,3), collapse = "")))
x
 [1] "pjnIKJ" "agjHGC" "pdaTSG" "lfcLEC" "ileGAC" "braKYE" "iruSQY" "aizPNR" "trpFPS" "zyoZKQ" "bmhCAE" "aorNCV" "fkeVYO" "naxLTV"
[15] "smeXZH"

gsub("[A-Z]*$", "", x)
 [1] "pjn" "agj" "pda" "lfc" "ile" "bra" "iru" "aiz" "trp" "zyo" "bmh" "aor" "fke" "nax" "sme"
x <- replicate(15, paste0(paste0(sample(letters,3), collapse = ""), paste0(sample(LETTERS,6), collapse = "")))
x
 [1] "rlfZYFDKT" "oauLJMIWT" "xvdDVNBFC" "wglBROVTN" "reqHGXEMC" "wtgXUFKTZ" "lewDLHOGA" "ujtYMATJH" "nldHQUZOT" "azdCQTWBR"
[11] "wjkYPOSNF" "lhvGZEJNV" "kjnKPCFUX" "tbaYTWQSL" "lwrPQHVFA"

gsub("[A-Z]*$", "", x)
"rlf" "oau" "xvd" "wgl" "req" "wtg" "lew" "ujt" "nld" "azd" "wjk" "lhv" "kjn" "tba" "lwr"