我正在尝试匹配一个模式:VD=
与字符串中第一次出现|
之间的任何内容,比如tmp
,如下所示:
tmp <- "PC=I;RS=128850544;RE=128850566;LEN=6;S1=36;S2=499.417;REP=2;VT=Ins;VD=SMO|CCDS5811.1|r.?|-|-|protein_coding:CDS:intron:insertion:intron_variant|SO:0000010:SO:0000316:SO:0000188:SO:0000667:SO:0001627;VC=intronic;VW=SMO|CCDS5811.1|r.?|-|-|protein_coding:CDS:intron:insertion:intron_variant|SO:0000010:SO:0000316:SO:0000188:SO:0000667:SO:0001627"
gene <- sub("^.*VD=([A-Za-z0-9]+)[|].*", "\\1", tmp)
gene
# [1] "SMO"
但是当字符串中没有VD=
或|
时,它会抓取整个字符串:
tmp <- "PC=D;RS=72450731;RE=72450735;LEN=1;S1=72;S2=802.939;REP=3;VT=Del"
gene <- sub("^.*VD=([A-Za-z0-9]+)[|].*", "\\1", tmp)
gene
# [1] "PC=D;RS=72450731;RE=72450735;LEN=1;S1=72;S2=802.939;REP=3;VT=Del"
即使没有NA
或VD=
个字符,我也不明白为什么它会抓取整个字符串而不是|
。有没有办法在第一次出现两个字符之间抓取一个模式并打印它,如果没有找到模式则打印NA。
非常感谢任何帮助。
谢谢!
答案 0 :(得分:4)
你的正则表达式看起来很复杂。使用像这样的简单正则表达式
正则表达式: VD=([^|]+)
就足够了。使用\\1
进行反向引用。
说明: ([^|]+)
匹配从VD=
到遇到第一个|
的任何内容。
<强> Regex101 Demo 强>
tmp <- c("PC=D;RS=72450731;RE=72450735;LEN=1;S1=72;S2=802.939;REP=3;VT=Del", "PC=I;RS=128850544;RE=128850566;LEN=6;S1=36;S2=499.417;REP=2;VT=Ins;VD=SMO|CCDS5811.1|r.?|-|-|protein_coding:CDS:intron:insertion:intron_variant|SO:0000010:SO:0000316:SO:0000188:SO:0000667:SO:0001627;VC=intronic;VW=SMO|CCDS5811.1|r.?|-|-|protein_coding:CDS:intron:insertion:intron_variant|SO:0000010:SO:0000316:SO:0000188:SO:0000667:SO:0001627")
gsub('VD=([^|]+)|.', '\\1', tmp)
# [1] "" "SMO"
答案 1 :(得分:1)
我认为你有效地尝试解析多级分隔的字符串。我建议不要尝试使用单个正则表达式来提取所需的信息,而是使用更严格的逐步细分语法元素。
首先,您可以拆分分号以获得看起来像变量赋值的顶级部分:
tmp <- 'PC=I;RS=128850544;RE=128850566;LEN=6;S1=36;S2=499.417;REP=2;VT=Ins;VD=SMO|CCDS5811.1|r.?|-|-|protein_coding:CDS:intron:insertion:intron_variant|SO:0000010:SO:0000316:SO:0000188:SO:0000667:SO:0001627;VC=intronic;VW=SMO|CCDS5811.1|r.?|-|-|protein_coding:CDS:intron:insertion:intron_variant|SO:0000010:SO:0000316:SO:0000188:SO:0000667:SO:0001627';
specs <- strsplit(fixed=T,tmp,';')[[1L]];
specs;
## [1] "PC=I"
## [2] "RS=128850544"
## [3] "RE=128850566"
## [4] "LEN=6"
## [5] "S1=36"
## [6] "S2=499.417"
## [7] "REP=2"
## [8] "VT=Ins"
## [9] "VD=SMO|CCDS5811.1|r.?|-|-|protein_coding:CDS:intron:insertion:intron_variant|SO:0000010:SO:0000316:SO:0000188:SO:0000667:SO:0001627"
## [10] "VC=intronic"
## [11] "VW=SMO|CCDS5811.1|r.?|-|-|protein_coding:CDS:intron:insertion:intron_variant|SO:0000010:SO:0000316:SO:0000188:SO:0000667:SO:0001627"
接下来,您可以搜索感兴趣的LHS,只提取第一次出现(如果有多个匹配):
vdspec <- grep(perl=T,value=T,'^VD=',specs)[1L];
vdspec;
## [1] "VD=SMO|CCDS5811.1|r.?|-|-|protein_coding:CDS:intron:insertion:intron_variant|SO:0000010:SO:0000316:SO:0000188:SO:0000667:SO:0001627"
您可以深入查看RHS,然后将其拆分为竖线分隔的字段:
vd <- sub(perl=T,'^VD=','',vdspec);
vd;
## [1] "SMO|CCDS5811.1|r.?|-|-|protein_coding:CDS:intron:insertion:intron_variant|SO:0000010:SO:0000316:SO:0000188:SO:0000667:SO:0001627"
vdfields <- strsplit(fixed=T,vd,'|')[[1L]];
vdfields;
## [1] "SMO"
## [2] "CCDS5811.1"
## [3] "r.?"
## [4] "-"
## [5] "-"
## [6] "protein_coding:CDS:intron:insertion:intron_variant"
## [7] "SO:0000010:SO:0000316:SO:0000188:SO:0000667:SO:0001627"
现在,您可以轻松获得您正在寻找的价值:
vdfields[1L];
## [1] "SMO"
如果您的目标LHS不匹配,您将从NA
来电中获得grep()[1L]
:
xxspec <- grep(perl=T,value=T,'^XX=',specs)[1L];
xxspec;
## [1] NA
因此,您可以对grep()[1L]
调用的结果进行分支,以处理缺少LHS的情况。