Regex 删除所需字符串前后与模式匹配的字母
我有一个包含以下元素的向量:Regex 删除所需字符串前后与模式匹配的字母,regex,r,Regex,R,我有一个包含以下元素的向量: myvec<- c("output.chr10.recalibrated", "output.chr11.recalibrated", "output.chrY.recalibrated") 我们可以使用str\u extract来执行此操作。我们匹配“chr”后面的一个或多个字符(*)((?)您只需子项即可: > sub(".*?chr(.*?)\\.recalibrated.*", "\\1", myvec) [1] "10" "11" "Y"
myvec<- c("output.chr10.recalibrated", "output.chr11.recalibrated",
"output.chrY.recalibrated")
我们可以使用
str\u extract
来执行此操作。我们匹配“chr”后面的一个或多个字符(*
)((?)您只需子项即可:
> sub(".*?chr(.*?)\\.recalibrated.*", "\\1", myvec)
[1] "10" "11" "Y"
sub(".*[.]chr([^.]*)[.].*", "\\1", myvec)
模式匹配第一个chr
之前的任何符号,然后匹配并捕获第一个之前的任何字符。重新校准的,然后匹配其余字符。在替换模式中,我们使用反向引用\1
,将所需捕获的值插入到结果字符串中
见
或者,使用str\u match
:
> library(stringr)
> str_match(myvec, "chr(.*?)\\.recalibrated")[,2]
[1] "10" "11" "Y"
它保留了所有捕获的值,并有助于避免模式中代价高昂的、在str\u extract
中必需的未配置的查找
该模式意味着:
chr
-匹配一系列文字字符chr
(.*)
-匹配除换行符以外的任何字符(如果您也需要匹配换行符,请在模式开头添加(?)s
)直到第一个字符
\\.重新校准
-。重新校准
文字字符序列
看起来像是XY问题。为什么提取?如果在进一步的分析步骤中需要提取,例如,我们可以这样做:
for(chrN in c(1:22, "X", "Y")) {
myVar <- paste0("output.chr", chrN, ".recalibrated")
#do some fun stuff with myVar
print(myVar)
}
(c中的chrN(1:22,“X”,“Y”)){
myVar两个答案在输入稍有不同的情况下都会失败,例如whatever.chr10.whateverelse.recalibrated
这里是我自己的方法,只是在正则表达式部分与sub
有所不同:
> sub(".*?chr(.*?)\\.recalibrated.*", "\\1", myvec)
[1] "10" "11" "Y"
sub(".*[.]chr([^.]*)[.].*", "\\1", myvec)
正则表达式的作用是:
*[.]chr
尽可能匹配,直到找到“.chr”为止
([^.]*)
捕获chr后的所有内容,而不是一个点(可替换为\\d+
以仅捕获数值,至少需要一个数字)
[.].*
在文字点后匹配行的其余部分
我更喜欢反斜杠转义(\.
)上的点字符类转义(\.
)当你回到正则表达式上时,通常更容易阅读,这是我的观点,我所知道的任何最佳实践都没有涵盖。非常感谢你。之间有什么区别?@MAPK我们使用正则表达式查找工具在chr
和之间选择一个或多个元素reclibrated@MAPK:环顾四周(零宽度断言,仅检查某些文本是否可以在字符串中的当前位置之前或之后匹配)对于str_extract
是必需的,因为此函数不保留捕获的值。仅为了我自己的头脑清醒:[.]chr([^.]*)[.]
在这种特定情况下应该与regex一样远。(不是在两个点之间包含chr之后的点字符)。旁注:投票赞成答案的完整性,清楚地解释了它是如何工作的,可能值得一提的是,*?
,因为非贪婪匹配更好)对不起,我很忙。*?
是一个,对,我只是想用人类的语言解释这个模式(…直到第一次。重新校准
)。我不会使用([^.]*)
,因为如果chr
和之间有点,它将不匹配。重新校准
。如果不能发生,那么是的,我会。很公平;)现在OP有他/她的Q可以被解释的两面性,这在我看来已经太多关注了。但是为什么你有whatever.chef10
当我们想要删除chr
?@MAPK时,它是一个打字错误;)修复了
sub(".*[.]chr([^.]*)[.].*", "\\1", myvec)