正则表达式选择2种子串

时间:2017-06-12 13:03:03

标签: r regex

我有像:

这样的字符串
  1. \n A vs B \n
  2. \n C vs D (EF) \n
  3. \n GH ( I vs J) \n
  4. 在名为myData的矢量中。

    以下是myData

    c("\n A vs B \n", "\n C vs D (EF) \n", "\n GH ( I vs J)\n")
    

    我想从1中选择A vs B,从2选择C vs D,从3选择I vs J

    我有以下代码:

    loc  = regexpr(".*vs.*|\\(.*vs.*\\)",myData,ignore.case=TRUE,perl=T)
    
    end  = loc  + attr(loc,"match.length")-1
    
    substr(myData,loc,end)
    

    给出三个输出:

    [1] " A vs B " " C vs D (EF) " " GH ( I vs J)"
    

    最后一场比赛不正确。我该如何解决这个问题?

3 个答案:

答案 0 :(得分:2)

我们可以使用str_extract

library(stringr)
str_extract(str1, "[A-Za-z]\\s*vs\\s*[A-Za-z]")
#[1] "A vs B" "C vs D" "I vs J"

或者,如果有其他小写字符代替' vs'

str_extract(str1, "[A-Z]\\s*[a-z]+\\s*[A-Z]")
#[1] "A vs B" "C vs D" "I vs J"

sub

中的base R
sub(".*([A-Z]\\s*[a-z]+\\s*[A-Z]).*", "\\1", str1)
#[1] "A vs B" "C vs D" "I vs J"

数据

str1 <- c("\n A vs B \n", "\n C vs D (EF) \n", "\n GH ( I vs J)\n")

答案 1 :(得分:2)

您可以使用与您的PCRE正则表达式相同的基础R regmatches / gregexpr解决方案,但使用外观,将.更改为[^()](以避免溢出括号)并将较长的替代品放在较小的替代品之前:

> myData <- c("\n A vs B \n", "\n C vs D (EF) \n", "\n GH ( I vs J)\n")
> res <- regmatches(myData, gregexpr("(?<=\\()[^()]*vs[^()]*(?=\\))|[^()]*vs[^()]*", myData, perl=TRUE))
> trimws(res)
[1] "A vs B" "C vs D" "I vs J"

请参阅R online demo

<强>详情:

  • (?<=\\() - 确保在当前位置左侧立即显示(的正面观察
  • [^()]* - 除()
  • 以外的0个字符
  • vs - 文字子字符串
  • [^()]* - 除()
  • 以外的0个字符
  • (?=\\)) - 确定当前位置右侧有)的正面预测
  • | - 或
  • [^()]*vs[^()]* - vs包含除()以外的0 +字符

注意:如果您需要防止跨行溢出,则需要将\r\n添加到[^()] - &gt; [^()\r\n]

请参阅this regex demo

答案 2 :(得分:2)

在混合中抛出非正则表达式方法。基本上我们在vs处拆分并用第二个元素的第一个字符粘贴第一个元素的最后一个字符。

sapply(strsplit(x, ' vs '), function(i) 
                      paste0(substr(i[1], nchar(i), nchar(i)), ' Vs ', substr(i[2], 1, 1)))

#[1] "A Vs B" "C Vs D" "I Vs J"