【问题标题】:Regular expression for the "opposite" result“相反”结果的正则表达式
【发布时间】:2014-07-11 01:05:36
【问题描述】:

取以下字符向量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>

【问题讨论】:

    标签: regex r gsub


    【解决方案1】:

    以下是一些建议:

    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"  
      

    【讨论】:

    • 很好的解释。非常感谢。
    【解决方案2】:

    这是一个使用三个正则表达式的解决方案。

    cap_words <- regmatches(x, regexpr("[A-Z][a-z]+", x))   # capitalised word
    last_words <- sub(".*\\s", "", x[grep("-", x)]) # get last word in strings with a dash
    c(cap_words, last_words)
    # [1] "Date"     "Number"   "Day"      "Visiting" "league" 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-25
      • 1970-01-01
      • 2022-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多