请考虑以下示例:
examples <- c(
"abc foo",
"abc foo 17",
"0 abc defg foo 5 121",
"abc 12 foo defg 11"
)
这里我想返回“foo”之后出现的第一个数字。在这种情况下:NA,17,5,11。我该怎么做?我尝试使用后视,但没有运气。
library(stringr)
str_extract(examples, "(?<=foo.*)[0-9]+")
Error in stri_extract_first_regex(string, pattern, opts_regex = opts(pattern)) :
Look-Behind pattern matches must have a bounded maximum length. (U_REGEX_LOOK_BEHIND_LIMIT)
答案 0 :(得分:5)
这似乎有效:
str_match(examples, "foo.*?(\\d+)")
[,1] [,2]
[1,] NA NA
[2,] "foo 17" "17"
[3,] "foo 5" "5"
[4,] "foo defg 11" "11"
来自?regex
:
默认情况下,重复是贪婪的,因此使用最大可能的重复次数。通过将
?
附加到量词,可以将其更改为“minimal”。
来自?str_extract
:
另见
?str_match
提取匹配的组;?stri_extract
用于底层实现。
答案 1 :(得分:1)
您可以使用base R solution like this:
> res <- gsub(".*?foo\\D*(\\d+).*|.*", "\\1", examples)
> res[nchar(res)==0] <- NA
> res
[1] NA "17" "5" "11"
由于正则表达式将始终匹配任何字符串,因此您无需再运行两次正则表达式替换,只需使用NA填充空值作为第二步。
模式匹配:
.*?foo
- 任意0个字符尽可能少(因为*?
是懒惰的)直到第一次出现foo
然后foo
本身\\D*
- 零个或多个非数字字符(\\d+)
- 捕获1个或多个数字的组1(之后,存储在组中的值可以通过\1
反向引用引用).*
- 字符串的其余部分|
- 或.*
- 即使是空的整个字符串。答案 2 :(得分:0)
基础R gsub
可以做到:
# pulls fist instance of a digit
gsub('^\\D*(\\d*).*', '\\1', examples)
[1] "" "17" "0" "12"
编辑:使用基础R的实际解决方案
ifelse(
grepl('foo\\D*\\d', examples),
gsub('^\\D*(\\d+).*', '\\1', gsub('.*foo\\s*', '', examples)),
NA)
[1] NA "17" "5" "11"