R 提取之间的字符串/
如果我有这些字符串:R 提取之间的字符串/,r,regex,R,Regex,如果我有这些字符串: mystrings <- c("X2/D2/F4", "X10/D9/F4", "X3/D22/F4", "X9/D22/F9") as.numeric(gsub(“^.*D([0-9]+).$”,“\\1”,mystrings))使用stru从stringr包中提取: as.numeric(str_extract(mystrings, perl('(?<=/[A-Z])
mystrings <- c("X2/D2/F4",
"X10/D9/F4",
"X3/D22/F4",
"X9/D22/F9")
as.numeric(gsub(“^.*D([0-9]+).$”,“\\1”,mystrings))
使用stru从stringr
包中提取:
as.numeric(str_extract(mystrings, perl('(?<=/[A-Z])[0-9]+(?=/)')))
as.numeric(str_extract)(mystrings,perl(')(?
您可以将该正则表达式模式“读取”(或“解析”)为将任何匹配的字符串拆分为三部分:
1) 包含第一个正斜杠和一系列大写字母的任何内容
2) 在下一个斜杠和之前的序列中的任何数字(“\d”)
3) 从下一个斜杠到最后
然后只返回第二部分
不匹配的字符串将原封不动地返回。@Arun抢走了我的风头,所以我给出了我最初冗长的示例
cut.to.pieces <- strsplit(mystrings, split = "/")
got.second <- lapply(cut.to.pieces, "[", 2)
get.numbers <- unlist(got.second)
as.numeric(gsub(pattern = "[[:alpha:]]", replacement = "", x = get.numbers, perl = TRUE))
[1] 2 9 22 22
cut.to.parties这最终成为@RomanLuštrik答案的压缩版本:
gsub("[^0-9]","",sapply(strsplit(mystrings,"/"),"[",2))
[1] "2" "9" "22" "22"
使用可能会使这类任务稍微简单一些
matches <- re_matches(mystrings,
rex(
"/",
any,
capture(name = "numbers", digits)
)
)
as.numeric(matches$numbers)
#>[1] 2 9 22 22
匹配[1]2922
使用软件包unglue,您可以执行以下操作:
#安装程序包(“unglue”)
图书馆(非蓝色)
unglue_vec(mystrings,“{x}/{y}/{z}”,var=“y”)
#>[1]“D2”“D9”“D22”“D22”
从数据帧中,您可以使用unglue\u unest()
,因此无需使用transform()
df列x y z
#>1根X2/D2/F4根X2根D2根F4根
#>2 X10/D9/F4 X10 D9 F4
#>3 X3/D22/F4 X3 D22 F4
#>4X9/D22/F9X9D22F9
#或者使用未命名的子模式仅保留中间值
unglue_unnest(df,col,“{=.*?}/{y}/{=.*?}”,remove=FALSE)
#>科利
#>1个X2/D2/F4 D2
#>2个X10/D9/F4 D9
#>3 X3/D22/F4 D22
#>4X9/D22/F9 D22
由(v0.3.0)于2019-11-06创建
更多信息:+1 for all@Arun给了我第一个可行的答案。我只是对字符串做得不够。+1我不知道你可以在没有第二组的情况下用\\2
抓取第二组匹配!光滑。@rrs这是look-behind断言的一部分。在R提示符中键入?regex
,然后阅读文章的最后几段“类Perl正则表达式”部分。
gsub("[^0-9]","",sapply(strsplit(mystrings,"/"),"[",2))
[1] "2" "9" "22" "22"
matches <- re_matches(mystrings,
rex(
"/",
any,
capture(name = "numbers", digits)
)
)
as.numeric(matches$numbers)
#>[1] 2 9 22 22
df <- data.frame(col = mystrings)
unglue_unnest(df, col, "{x}/{y}/{z}", remove = FALSE)
#> col x y z
#> 1 X2/D2/F4 X2 D2 F4
#> 2 X10/D9/F4 X10 D9 F4
#> 3 X3/D22/F4 X3 D22 F4
#> 4 X9/D22/F9 X9 D22 F9
# or used unnamed subpatterns to keep only the middle value
unglue_unnest(df, col, "{=.*?}/{y}/{=.*?}", remove = FALSE)
#> col y
#> 1 X2/D2/F4 D2
#> 2 X10/D9/F4 D9
#> 3 X3/D22/F4 D22
#> 4 X9/D22/F9 D22