废话不多说,我们来聊聊今天的正题。昨天有位群友在群里提出了这样一个问题
具体的字符串向量是这样的,需要达到的目的就是,看字符串向量里面的每一个元素是否包含"LIPE2"这个基因。这里的字符串向量有四个元素。
实现的手段就是通过R的grepl函数
这个函数里的pattern是匹配的模式,也就是我们经常听到的正则表达式。如果对正则表达式还不了解的小伙伴,可以参考☞正则表达式☜。x就是要查看是否满足pattern的字符串向量,如果匹配pattern就返回TRUE,不满足就返回FASLE。
这位群友所提出的问题,tricky的地方在于LIPE2这个基因有时候存在于字符串的中间,有时候存在于开头,有时候又存在于末尾,并且还需要考虑一些干扰项比如LIPE23这个基因也能够匹配LIPE2,似乎很难通过一个正则表达式来实现。后来这位群友自己解决了这个问题,方法就是通过或来实现。既然一个正则表达式无法满足需要,那就多写几个正则表达式,把所有可能的情况都考虑进去。
这个问题引起了群里关于正则表达式激烈的讨论,
其实,在这个群友提出这个问题之前,我还不太确定,pattern里面可以使用或(|),通过讨论大家都有所收获,至少群里的其他小伙伴知道了正则表达式这个概念。以后遇到相似的问题,也知道怎么解决了。
今天我又仔细的研究了一下,给出了三种实现的方法,供大家交流学习。我又加入了一个干扰项,让这个正则表达式更全面。
代码语言:javascript复制s <- c("ABCLIPE2", #LIPE2前面有干扰
"LIPE-AS1,LIPE,CXCL17",
"LIPE-AS1,LIPE2,LIPE,CXCL17", #LIPE2在中间,前后都有,
"LIPE2", #LIPE2在字符串的开始,或者结尾
"LIPE23") #LIPE2后面有干扰
方法一,直接匹配所有可能的情况
代码语言:javascript复制#^LIPE2$:匹配整个字符串只有LIPE2这个基因,^锚定开始,$锚定结尾
#,LIPE2,:匹配LIPE2在中间,前后都有其他基因
#^LIPE2,:匹配LIPE2在开始,后面有基因
#,LIPE2$:匹配LIPE2在结尾,前面有基因
#|是或,即满足其中任何一个条件即可
grepl("^LIPE2$|,LIPE2,|^LIPE2,|,LIPE2$",s)
#[1] FALSE FALSE TRUE TRUE FALSE
方法二,利用b,单词边界
代码语言:javascript复制#b匹配一个单词边界,也就是指单词和空格间的位置。
#例如,“erb”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”。
grepl("\bLIPE2\b",s)
#[1] FALSE FALSE TRUE TRUE FALSE
方法三,利用strsplit和%in%
代码语言:javascript复制sapply(s,function(x){
'LIPE2' %in% strsplit(x,',')[[1]]
})
返回的结果是
如果对strsplit还不熟悉的小伙伴,其实可以先输出来看看结果
代码语言:javascript复制sapply(s,function(x){
strsplit(x,',')[[1]]
})
返回的结果是分割之后的字符串向量
参考资料:
- 正则表达式
- https://www.rdocumentation.org/packages/base/versions/3.6.2/topics/strsplit
- https://www.rdocumentation.org/packages/base/versions/3.6.2/topics/grep