我需要一个正则表达式,返回一个特定的字母和下面的(一个或两个)数字,直到下一个字母.
例如,我想在R中使用正则表达式提取公式中有多少个碳(C)
例如,我想在R中使用正则表达式提取公式中有多少个碳(C)
strings <- c("C16H4ClNO2","CH8O","F2Ni")
我需要一个表达式,它返回C的数字,可以是一个或两个数字,并且在氯(Cl)之后不返回数字.
substr(strings,regexpr("C[0-9]+",strings) + 1,regexpr("[ABDEFGHIJKLMNOPQRSTUVWXYZ]+",strings) -1) [1] "16" "C" ""
但我想要回答的答案是
"16","1","0"
此外,我希望正则表达式自动定位下一个字母并在它之前停止,而不是具有我指定为不是C的字母的最终位置.
解决方法
CHNOSZ包中的化妆将解析化学式.以下是一些使用它的替代方案:
1)创建一个这样完全解析的公式的列表L,然后为每个公式检查它是否具有“C”组件并返回其值,如果没有则返回0:
library(CHNOSZ) L <- Map(makeup,strings) sapply(L,function(x) if ("C" %in% names(x)) x[["C"]] else 0) ## C16H4ClNO2 CH8O F2Ni ## 16 1 0
请注意,如果您有其他要求,L是完全解析的公式的列表:
> L $C16H4ClNO2 C H Cl N O 16 4 1 1 2 $CH8O C H O 1 8 1 $F2Ni F Ni 2 1
1a)通过向每个列表组件添加c(C = 0),我们可以避免必须测试碳的存在,从而产生以下(1)中的sapply线的较短版本:
sapply(lapply(L,c,c(C = 0)),"[[","C")
2)除了名称之外,(1)的这种单线变化给出了与(1)中相同的答案.它为每个配方添加“C0”以避免必须测试碳的存在:
sapply(lapply(paste0(strings,"C0"),makeup),"C") ## [1] 16 1 0
2a)这是(2)的变体,通过使用化妆将接受矩阵的事实来消除lapply:
sapply(makeup(as.matrix(paste0(strings,"C0"))),"C") ## [1] 16 1 0