提问人:vizidea 提问时间:10/21/2023 更新时间:10/23/2023 访问量:79
使用 R gsub 仅从字符串中返回两位数字符?
Using R gsub to only return double digit characters from string?
问:
我有一个变量,其值如下:
example <- c("positive_1", "positive_2", "test_20_curve", "test_60_point", "percent_total")
有没有办法只从向量中返回“20”和“60”?
我目前有
gsub(".*([0-9]{2}).*", "\\1", example)
哪个输出
[1] "positive_1" "positive_2" "20" "60" "percent_total"
我想知道是否有一种方法可以使任何没有两位数的值显示为 NA。
提前致谢!
答:
2赞
Wiktor Stribiżew
10/21/2023
#1
stringr::str_extract
方法
你可以使用
example <- c("positive_1", "positive_2", "test_20_curve", "test_60_point", "percent_total")
library(stringr)
str_extract(example, "(?<!\\d)\\d{2}(?!\\d)")
## => [1] NA NA "20" "60" NA
请参阅 R 演示。注意:提取模式的第一个匹配项。如果需要最后一个,请使用 and,然后 .str_extract
library(stringi)
stri_extract_last_regex(example, "(?<!\\d)\\d{2}(?!\\d)")
细节:
(?<!\d)
- 在左边,不能有数字\d{2}
- 两位数(?!\d)
- 不紧跟另一个数字。
sub
方法
example <- c("positive_1", "positive_2", "test_20_curve", "test_60_point", "percent_total")
res <- sub("^(?:(?:.*\\D)?(\\d{2})(?:\\D.*)?|.+)$", "\\1", example)
res <- res[nzchar(res)]
res
## => [1] "20" "60"
请参阅 R 演示。
图案细节
^
- 字符串的开头(?:
- 以下两种选择之一:- |.+)
(?:.*\D)?
- 任何非数字字符的可选序列,然后是字符串的其余部分(\d{2})
- 第 1 组(替换模式中指值):两位数\1
(?:\D.*)?
- 任何非数字字符的可选序列,然后是字符串的其余部分
|
-或.+
- 一个或多个字符,尽可能多的字符
)
- 外部分组的末尾(以便任一模式部分可以匹配整个字符串)$
- 字符串末尾。
注意这里就足够了,因为我们在整个字符串匹配时执行一次替换。sub
如果字符串中没有只有 2 位数字,则 的结果将是一个空字符串,因此我们需要使用 来摆脱它们。sub
res <- res[nzchar(res)]
注意:如果出现多个 2 位数字,则使用此方法返回最后一个数字。要获取第一个,请使用 .sub("^(?:(?:.*?\\D)?(\\d{2})(?:\\D.*)?|.+)$", "\\1", example, perl=TRUE)
1赞
TarJae
10/21/2023
#2
我们首先提取两位数
然后,我们检查向量的每个元素中是否有一个两位数,并且
将其他替换为 NAgsub
grepl
example <- c("positive_1", "positive_2", "test_20_curve", "test_60_point", "percent_total")
x <- gsub(".*?([0-9]{2}).*", "\\1", example)
x[!grepl("[0-9]{2}", example)] <- NA
x
[1] NA NA "20" "60" NA
评论
1赞
GuedesBF
10/21/2023
提取数字两次对我来说看起来有点太奇怪了。至少应该有点低效。为什么不在步骤#2中使用更简单的解决方案呢?nchar
1赞
DuesserBaest
10/23/2023
#3
怎么样:
example <- c(
"positive_1",
"positive_2",
"test_20_curve",
"test_60_point",
"percent_total"
)
res <- sub("^\\D+(\\d{2})?\\D.*$", "\\1", example)
res[grepl("^$", res)] <- NA
res
输出:
[1] NA NA "20" "60" NA
\\D+
测试非数字,然后
(\\d{2})
捕获的两个数字,后跟
\\D*
任意数量的非数字,确保匹配的位数不超过两位。
一切都匹配,只有捕获的两位数字被替换。
NA
为任何空字符串插入。
评论