我需要一个正则表达式,它返回一个特定的字母和下面的(一个或两个)数字,直到下一个字母。 例如,我想在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的字母。
答案 0 :(得分:9)
makeup
将解析化学式。以下是一些使用它的替代方案:
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)
,我们可以避免测试碳的存在,从而产生以下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
接受矩阵的事实来消除makeup
:
sapply(makeup(as.matrix(paste0(strings, "C0"))), "[[", "C")
## [1] 16 1 0
答案 1 :(得分:1)
如果我理解你的问题,你就会找两件事:
如果您能够安装另一个库,您可能会相处:
library("stringr")
strings <- c("C16H4ClNO2", "CH8O", "F2Ni")
str1 <- str_extract(strings, '(?<=C)\\d+')
str2 <- str_count(strings, 'C[A-Z]')
str2[!is.na(str1)] = str1[!is.na(str1)]
str2
# [1] "16" "1" "0"
这有很多奇特的东西,str1
寻找第一个条件(C后跟另一个数字),而str2
寻找第二个条件。最后一行结合了两个向量
答案 2 :(得分:0)
我们可以使用base R
sub("C(\\d+).*", "\\1", sub("C([^0-9]+)",
"C1\\1", ifelse(!grepl("C", strings), paste0("C0", strings), strings)))
#[1] "16" "1" "0"
答案 3 :(得分:0)
ifelse(str_extract(strings,'(?<=C)(\\d+|)')=='',1,str_extract(strings,'(?<=C)(\\d+|)'))
[1] "16" "1" NA