我有以下字符向量,其中包括括号、句号和不必要的描述性词语
strings <- c("Poorly Graded Silty Sand (SP-SM).", "(Visual) Lean Clay (CL), with some sand.","Poorly Graded Silty Sand (SP-SM).","(Visual) Inorganic Silt (ML).","(Visual) Lean Clay (CL), with some sand.")
我希望只提取位于每行括号内的字母编码系统(例如:ML或SP-SM)。这是想要的向量。
need <- c("SP-SM", "CL","SP-SM","ML","CL")
这可能吗?
我们可以使用带有正则表达式的str_extract
来匹配左括号后面跟着一个或多个大写字母的-
,后面跟着右括号
library(stringr)
str_extract(strings, "(?<=\()[A-Z-]+(?=\))")
[1] "SP-SM" "CL" "SP-SM" "ML" "CL"
这是akrun解决方案的长版本:
str_extract(strings, '\b[A-Z]{2}\b\-\b[A-Z]{2}\b|\b[A-Z]{2}\b')
输出:
[1] "SP-SM" "CL" "SP-SM" "ML" "CL"
解释:
[A-Z]{2}
匹配两个大写字母
\-
匹配连字符。
\b
单词字符和非单词字符之间的匹配。
|
定义OR
这可以是base R中的另一个选项:
unlist(regmatches(strings, gregexpr("(?<=\()[[:upper:]]{1,}(-[[:upper:]]{1,})?(?=\))", strings, perl = TRUE)))
[1] "SP-SM" "CL" "SP-SM" "ML" "CL"
请注意,我使用可选字符串?
为第二个可能的子字符串,因为它可能不存在:(-[[:upper:]]{1,})?
(?<=\()
正面向后看。它匹配任何前面有圆括号(
的字符串(?<=\()
正面展望。它匹配任何后跟圆括号)
的字符串。[[:upper:]]{1,}
匹配大于1个大写字母