regex - "opposite"结果的正则表达式

标签 regex r gsub

取以下字符向量x

x <- c("1     Date in the form", "2     Number of game", 
       "3     Day of week", "4-5     Visiting team and league")

我想要的结果是以下向量,其中每个字符串中的第一个大写单词,并且如果字符串包含 - ,也是最后一句话。

[1] "Date"     "Number"   "Day"      "Visiting" "league"  

所以而不是这样做

unlist(sapply(strsplit(x, "[[:blank:]]+|, "), function(y){
   if(grepl("[-]", y[1])) c(y[2], tail(y,1)) else y[2] 
}))

为了得到结果,我想我可以尝试将其缩短为正则表达式。结果几乎与 sub 中的这个正则表达式“相反” 。我已经尝试了各种方法来获得相反的结果,使用不同品种的[^A-Za-z]+等等,但尚未成功。

> sub("[A-Z][a-z]+", "", x)
[1] "1      in the form"       "2      of game"           
[3] "3      of week"           "4-5      team and league"

所以我想这是一个由两部分组成的问题。

  1. sub()gsub() ,如何返回 "[A-Z][a-z]+" 的相反值?

  2. 如何将正则表达式编写为“匹配第一个大写单词,如果字符串包含 -,则还匹配最后一个单词。”? p>

最佳答案

以下是一些建议:

  1. 要使用 sub 提取第一个大写单词,您可以使用

    sub(".*\\b([A-Z].*?)\\b.*", "\\1", x)
    #[1] "Date"     "Number"   "Day"      "Visiting"
    

    其中 \\b 表示单词边界。

  2. 您还可以使用一个 sub 命令提取所有单词,但请注意,您必须应用额外的步骤,因为 sub 返回的向量长度与输入向量x的长度相同。

    以下正则表达式使用前瞻 ((?=.*-)) 来测试字符串中是否存在 -。如果是这种情况,则提取两个词。如果不存在,则应用逻辑 or (|) 之后的正则表达式,并仅返回第一个大写单词。

    res <- sub("(?:(?=.*-).*\\b([A-Z].*?\\b ).*\\b(.+)$)|(?:.*\\b([A-Z].*?)\\b.*)", 
               "\\1\\2\\3", x, perl = TRUE)
    # [1] "Date"            "Number"          "Day"             "Visiting league"
    

    为了分隔同一字符串中的多个单词,还需要一个额外的步骤:

    unlist(strsplit(res, " ", fixed = TRUE))
    # [1] "Date"     "Number"   "Day"      "Visiting" "league"  
    

关于regex - "opposite"结果的正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24670038/

相关文章:

regex - Perl split 函数 - 使用重复字符作为分隔符

r - 过滤数据框

r - 使用 ggplot2 中子图的自定义 x,y 位置创建子图(小平面)

删除R中数据中不必要的符号

regex - Grep regex捕获不带端口的IP套接字

JavaScript 使用正则表达式替换所有多行空格和其他空白字符

r - ChartSeries - 如何将绘图 x 标签设置为数据框中的原始日期

r - 如何在R中用相同的字符串替换多个字符串

在不改变其他词的情况下替换R中的文本

php - 在 Python 中替换字符串时可以传递字典吗?