从R中的字符串中提取数字和文本

时间:2016-06-18 23:57:23

标签: r

我有一个字符串,想要提取每个数字旁边的第一组三个数字和任意三个字母,然后放入一个矢量。所以这个:

t1 <- "The string contains numbers ranging from 3-4 cm and can reach up to 5.6 m long, and sometimes can even reach 10 m."

t1将成为:

"3-4 cm", "5.6 m", "10m"

我查找了各种正则表达式函数,如grep,grepl等,但无法找到与我的查询匹配的示例。 有什么建议吗?

2 个答案:

答案 0 :(得分:1)

以下是gregexpr() + regmatches()如何做到这一点:

ipartRE <- '\\d+';
fpartRE <- '\\.\\d+';
numRE <- paste0(ipartRE,'(?:',fpartRE,')?');
rangeRE <- paste0(numRE,'(?:\\s*-\\s*',numRE,')?');
pat <- paste0(rangeRE,'\\s*[a-zA-Z]{1,3}\\b');
regmatches(t1,gregexpr(perl=T,pat,t1))[[1L]];
## [1] "3-4 cm" "5.6 m"  "10 m"

为了人类的可读性,我逐渐从组件部分逐步建立了正则表达式,但显然你不需要这样做。

为了匹配新模式,我们需要接受第二个数字的替换,该数字在数字周围采用匹配的括号。我还发现120(–150) cm中的短划线不是正常ASCII hyphen,而是en dash,因此我添加了另一个名为dashRE的预先计算的正则表达式片段,它匹配所有3常见的短划线类型(ASCII,短划线和em dash):

ipartRE <- '\\d+';
fpartRE <- '\\.\\d+';
numRE <- paste0(ipartRE,'(?:',fpartRE,')?');
dashRE <- '[—–-]';
rangeOptParenRE <- paste0(numRE,'(?:\\s*(?:',dashRE,'\\s*',numRE,'|\\(\\s*',dashRE,'\\s*',numRE,'\\s*\\)\\s*))?');
pat <- paste0(rangeOptParenRE,'\\s*[a-zA-Z]{1,3}\\b');
regmatches(t1,gregexpr(perl=T,pat,t1))[[1L]];
## [1] "3-4 cm"       "120(–150) cm" "5.6 m"        "10 m"

答案 1 :(得分:0)

您可以尝试使用此正则表达式[0-9.-]+\\s+[a-zA-z]{1,3}并使用str_extract_all包中的stringr来提取它们:

stringr::str_extract_all(t1, "[0-9.-]+\\s+[a-zA-Z]{1,3}")
[[1]]
[1] "3-4 cm" "5.6 m"  "10 m"