【发布时间】:2014-12-01 22:12:43
【问题描述】:
string = "ABC3JFD456"
假设我有上面的字符串,我想找出字符串中的第一个数字是什么并存储它的值。在这种情况下,我想存储值 3(因为它是字符串中第一个出现的数字)。 grepl("\\d", string) 只返回一个逻辑值,但没有告诉我第一个数字在哪里或是什么。我应该使用哪个正则表达式来查找第一个数字的值?
【问题讨论】:
string = "ABC3JFD456"
假设我有上面的字符串,我想找出字符串中的第一个数字是什么并存储它的值。在这种情况下,我想存储值 3(因为它是字符串中第一个出现的数字)。 grepl("\\d", string) 只返回一个逻辑值,但没有告诉我第一个数字在哪里或是什么。我应该使用哪个正则表达式来查找第一个数字的值?
【问题讨论】:
基础R
regmatches(string, regexpr("\\d", string))
## [1] "3"
或使用stringi
library(stringi)
stri_extract_first(string, regex = "\\d")
## [1] "3"
或者使用stringr
library(stringr)
str_extract(string, "\\d")
## [1] "3"
【讨论】:
1) sub 使用指定的正则表达式尝试sub,它将最短的字符串直到一个数字,一个数字,然后是后面的所有内容,并将其替换为数字:
sub(".*?(\\d).*", "\\1", string)
给予:
[1] "3"
如果string 是一个字符串向量,这也有效。
2) strapplyc 也可以使用gsubfn 中的strapplyc,在这种情况下可以使用更简单的正则表达式:
strapplyc(string, "\\d", simplify = TRUE)[1]
给出相同的答案或使用 this 再次给出相同的答案,但如果 string 是字符串向量,也可以:
sapply(strapplyc(string, "\\d"), "[[", 1)
【讨论】:
获取数字的位置
tmp <- gregexpr("[0-9]", string)
iloc <- unlist(tmp)[1]
提取第一个数字
as.numeric(substr(string,iloc,iloc))
使用正则表达式更简单
tmp<-regexpr("[0-9]",string)
if(tmp[[1]]>=0) {
iloc <- tmp[1]
num <- as.numeric(substr(string,iloc,iloc))
}
【讨论】:
regexpr,只会返回[0-9]的第一个命中。
使用rex 可能会使此类任务更简单一些。
string = c("ABC3JFD456", "ARST4DS324")
re_matches(string,
rex(
capture(name = "first_number", digit)
)
)
#> first_number
#> 1 3
#> 2 4
【讨论】:
> which( sapply( strsplit(string, ""), grepl, patt="[[:digit:]]"))[1]
[1] 4
或者
> gregexpr("[[:digit:]]", string)[[1]][1]
[1] 4
所以:
> splstr[[1]][ which( sapply( splstr, grepl, patt="[[:digit:]]"))[1] ]
[1] "3"
请注意,gregexpr 调用的完整结果是一个列表,因此需要使用 "[[":
提取其第一个元素> gregexpr("[[:digit:]]", string)
[[1]]
[1] 4 8 9 10
attr(,"match.length")
[1] 1 1 1 1
attr(,"useBytes")
[1] TRUE
【讨论】:
string[4] 不起作用
regmatches David Arenburg 的回答使用的将是我认为从字符串中提取正则表达式匹配的首选基本 R 方法。此外,regexpr 将消除对gregexpr 的结果进行子集化的需要
gsub 解决方案基于用空字符串替换第一个数字之前和之后的子字符串:
gsub("^\\D*(?=\\d)|(?<=\\d).*", "", string, perl = TRUE)
# [1] "3"
【讨论】: