提取2个字符串部分

时间:2016-11-10 10:47:49

标签: r regex

假设我有以下字符串(文件名):

a <- "X/ZHEB100/TKN_VAR29380_timely_p1.txt"

由几个部分组成(这里给出了p1)

或另一个

b <- "X/ZHEB100/ZHN_VAR29380_timely.txt"

仅由一部分组成(因此无需标记任何p)

如何提取标识符,即VARXXXXX之前的三个字母(如果是TKN,则为两个字母ZHN)加上部件标识符(如果有)?

所以结果应该是:

case1 : TKN_p1
case2 : ZHN

我知道如何提取第一个标识符,但我无法同时处理第二个标识符。

到目前为止我的方法:

sub(".*(.{3})_VAR29380_timely(.{3}).*","\\1\\2", a)
sub(".*(.{3})_VAR29380_timely(.{3}).*","\\1\\2", b)

但在第二种情况下,这会错误地添加.tx

2 个答案:

答案 0 :(得分:2)

您没有使用锚点并且在timely之后立即匹配最后3个字符,而没有检查这些字符是什么(.匹配任何字符)。

我建议

sub("^.*/([A-Z]{3})_VAR\\d+_timely(_[^_.]+)?\\.[^.]*$", "\\1\\2", a)

<强>详情:

  • ^ - 字符串开头
  • .*/ - 字符串的一部分,包括最后一个/
  • ([A-Z]{3}) - 将3个ASCII大写字母捕获到第1组
  • _VAR\\d+_timely - _VAR + 1位或更多位+ _timely
  • (_[^_.]+)? - 可选第2组捕获_ + 1个或更多字符而不是_.
  • \\. - 一个点
  • [^.]* - 除.
  • 以外的零个或多个字符
  • $ - 字符串结束。

替换模式包含两个对两个捕获组的反向引用,以将其内容插入到替换的字符串中。

R demo

a <- "X/ZHEB100/TKN_VAR29380_timely_p1.txt"
a2 <- sub("^.*/([A-Z]{3})_VAR\\d+_timely(_[^_.]+)?\\.[^.]*$", "\\1\\2", a)
a2
[1] "TKN_p1"
b <- "X/ZHEB100/ZHN_VAR29380_timely.txt"
b2 <- sub("^.*/([A-Z]{3})_VAR\\d+_timely(_[^_.]+)?\\.[^.]*$", "\\1\\2", b)
b2
[1] "ZHN"

答案 1 :(得分:1)

另一种解决方案,与Wiktor已有的解决方案不同的是:

library( magrittr )
data <- c( a, b )

首先得到&#34; ID&#34;通过拆分&#34; /&#34;,取最后一个值,然后取前三个字符:

ID <- strsplit( data, "/" ) %>%
    sapply( tail, n = 1 ) %>%
    substr( 1, 3 )

然后得到&#34;部分&#34;通过拆分&#34;及时&#34;和&#34; .txt&#34;,并取最后一个元素(可能是一个空字符串):

part <- strsplit( data, "timely|.txt" ) %>%
    sapply( tail, n = 1 )

现在只需将它们粘贴在一起即可获得结果:

output <- paste0( ID, part )
output
[1] "TKN_p1" "ZHN"

或者,如果您不想创建中间对象:

output <- strsplit( data, "/" ) %>%
    sapply( tail, n = 1 ) %>%
    substr( 1, 3 ) %>%
    paste0( strsplit( data, "timely|.txt" ) %>%
                      sapply( tail, n = 1 ) )