我需要从一些字符串中提取子字符串,例如:
我的数据是矢量:c("Shigella dysenteriae","PREDICTED: Ceratitis")
a = "Shigella dysenteriae"
b = "PREDICTED: Ceratitis"
我希望如果字符串以“ PREDICTED:”开头,则可以将其提取到后续单词(可能是“ Ceratitis”),并且如果字符串不是以“ PREDICTED”开头,则可以将其提取为第一个字(也许是志贺氏菌);
在此示例中,结果将是:
result_of_a = "Shigella"
result_of_b = "Ceratitis"
好吧,这是一个典型的条件正则表达式。我试过,但总是失败;
我使用了R
,它可以兼容perl
的正则表达式。
我知道R支持perl
的正则表达式,因此我尝试使用regexpr
和regmatches
这两个函数来提取所需的子字符串。
代码是:
pattern = "(?<=PREDICTED:)?(?(1)(\\s+\\w+\\b)|(\\w+\\b))"
a = c("Shigella dysenteriae")
m_a = regexpr(pattern,a,perl = TRUE)
result_a = regmatches(a,m_a)
b = c("PREDICTED: Ceratitis")
m_b = regexpr(pattern,a,perl = TRUE)
result_b = regmatches(b,m_b)
最后,结果是:
# result_a = "Shigella"
# result_b = "PREDICTED"
这不是我期望的结果,result_a是正确的,result_b是错误的。
为什么?看来条件不起作用...
PS: 我试图阅读一些条件reg-expression的细节。这是我尝试阅读的网络:https://www.regular-expressions.info/conditional.html,我尝试从该网络模仿“模式”,还尝试使用“ RegexBuddy”软件查找原因。
答案 0 :(得分:2)
我认为它不起作用的原因是因为(1)
checks if a numbered capture group has been set,但是还没有设置第一个捕获组,也没有出现在(?<=PREDICTED:)?
后面的正面。
接下来的部分中有一个第一和第二捕获组。 if子句将检查组1,未设置它,因此它将匹配组2。
如果将其设为唯一的捕获组(?<=(PREDICTED: )?)
并省略其他2个,则if子句为true,但由于后向断言不是fixed length,您会收到错误消息。
除了使用条件模式,要获取两个单词,您可以使用捕获组并将PREDICTED:
设为可选:
^(?:PREDICTED: )?(\w+)
答案 1 :(得分:1)
编辑:
要将以下函数用于矢量,可以执行以下操作:
向量:myvec<-c("Shigella dysenteriae","PREDICTED: Ceratitis")
lapply(myvec,extractor)
[[1]]
[1] "Shigella"
[[2]]
[1] "Ceratitis"
或者:
unlist(lapply(myvec,extractor))
[1] "Shigella" "Ceratitis"
这假定字符串始终采用上面显示的格式:
extractor<- function(string){
if(grepl("^PREDICTED",string)){
strsplit(string,": ")[[1]][2]
}
else{
strsplit(string," ")[[1]][1]
}
}
extractor(b)
#[1] "Ceratitis"
extractor(a)
#[1] "Shigella"
答案 2 :(得分:0)
如果我理解正确,则OP要提取
因此,如果没有特定要求仅使用一个正则表达式,这就是我要做的:
对于使用正则表达式,我更喜欢使用Hadley Wickham的stringr
软件包:
inp <- c("Shigella dysenteriae", "PREDICTED: Ceratitis")
library(magrittr) # piping used to improve readability
inp %>%
stringr::str_replace("^PREDICTED:\\s*", "") %>%
stringr::str_extract("^\\w+")
[1] "Shigella" "Ceratitis"
为了安全起见,我会事先删除所有前导空格:
inp %>%
stringr::str_trim() %>%
stringr::str_replace("^PREDICTED:\\s*", "") %>%
stringr::str_extract("^\\w+")