R-regex在短划线和句点之间提取字符串

时间:2016-02-15 07:15:51

标签: regex r

首先,如果这个问题过于天真或早些时候重复,我会道歉。我试图在论坛中找到它,但我将其作为一个问题发布,因为我没有找到答案。

我的数据框的列名如下;

head(rownames(u))

[1] "A17-R-Null-C-3.AT2G41240"       "A18-R-Null-C-3.AT2G41240"         "B19-R-Null-C-3.AT2G41240"      
[4] "B20-R-Null-C-3.AT2G41240"       "A21-R-Transgenic-C-3.AT2G41240" "A22-R-Transgenic-C-3.AT2G41240"

我想要的是在R中使用正则表达式来提取第一个短划线和最后一个周期之间的字符串。

预期结果是,

[1] "R-Null-C-3"       "R-Null-C-3"         "R-Null-C-3"      
[4] "R-Null-C-3"       "R-Transgenic-C-3" "R-Transgenic-C-3"

我试着追随没有运气......

gsub("^[^-]*-|.+\\.","\\2", rownames(u))
gsub("^.+-","", rownames(u))
sub("^[^-]*.|\\..","", rownames(u))

有人能帮我解决这个问题吗?

提前多多感谢。

沙尼。

4 个答案:

答案 0 :(得分:4)

以下是与gsub一起使用的解决方案:

v <- c("A17-R-Null-C-3.AT2G41240", "A18-R-Null-C-3.AT2G41240", "B19-R-Null-C-3.AT2G41240", "B20-R-Null-C-3.AT2G41240", "A21-R-Transgenic-C-3.AT2G41240", "A22-R-Transgenic-C-3.AT2G41240")
gsub("^[^-]*-([^.]+).*", "\\1", v)

请参阅IDEONE demo

regex matches

  • ^[^-]* - 除-
  • 以外的零个或多个字符
  • - - 连字符
  • ([^.]+) - 第1组匹配并捕获除点之外的一个或多个字符
  • .* - 任何字符(甚至包括未使用perl=T以来的换行符),字符串末尾的任意数量的出现次数。

答案 1 :(得分:2)

正则表达式

-([^.]+)\\.

Regular expression visualization

描述

- matches the character - literally
    1st Capturing group ([^\\.]+)
        [^\.]+ match a single character not present in the list below
            Quantifier: + Between one and unlimited times, as many times as possible, giving back as needed [greedy]
        . matches the character . literally
    \\. matches the character . literally

Debuggex Demo

输出

MATCH 1
1.  [4-14]  `R-Null-C-3`
MATCH 2
1.  [29-39] `R-Null-C-3`
MATCH 3
1.  [54-64] `R-Null-C-3`
MATCH 4
1.  [85-95] `R-Null-C-3`
MATCH 5
1.  [110-126]   `R-Transgenic-C-3`
MATCH 6
1.  [141-157]   `R-Transgenic-C-3`

答案 2 :(得分:2)

使用以下正则表达式可以很容易地实现这一点:

-([^.]+)
# look for a dash
# then match everything that is not a dot
# and save it to the first group

a demo on regex101.com。输出是:

R-Null-C-3
R-Null-C-3
R-Null-C-3
R-Null-C-3
R-Transgenic-C-3
R-Transgenic-C-3

答案 3 :(得分:2)

这似乎是lookarounds的合适案例:

library(stringr)
str_extract(v, '(?<=-).*(?=\\.)')

其中

  • (?<= ... )是一个肯定的后瞻,即它会在下一个被捕获的群组之前寻找-;
  • .*是任何字符.重复0次或更多次*;
  • (?= ... )是一个肯定的前瞻,即它会根据实际捕获的内容查找一段时间(转义为\\.)。

我之前使用过stringr::str_extract因为它在您尝试做的事情方面更直接。可以使用sub(或gsub)执行相同的操作,但正则表达式必须更加丑陋:

sub('.*?(?<=-)(.*)(?=\\.).*', '\\1', v, perl = TRUE)
  • .*?查找任意字符.,从0到尽可能少*?(懒惰评估);
  • lookbehind (?<=-)与上面相同;
  • 现在,我们想要的部分.*被放入捕获的群组(...)中,我们以后需要这些群体;
  • 前瞻(?=\\.)是一样的;
  • .*捕获任何字符,重复0到尽可能多的时间(这里是字符串的结尾)。
  • 替换为\\1,它指的是模式正则表达式中第一个捕获的组。