正则表达式分组和重新排序

regex grouping and re-ordering

恐怕我有一个正则表达式问题。我想提取字符串的第一组,即 1 位,省略第二组,即 2 位,然后提取结尾的 5 位作为第三组。

在我看来它应该是这样的:str_extract(a, "(\d{1})(\d{2})(\d{5})\1\3")。但那是行不通的。

示例数据在这里,也是想要的结果,但表达式不同:

library(tidyverse)

d <- tibble(a = as.character(as.integer(runif(10, 1e8, 2e8))) )

d %>%
  mutate(want_but_wrong_regex = str_remove(a, "(?<=\d)\d{2}")) # 

# A tibble: 10 x 2
#a         want_but_wrong_regex
#<chr>     <chr>               
#  1 103016397 1016397             
#2 164356395 1356395             
#3 134615352 1615352             
#4 176581897 1581897             
#5 127035705 1035705             
#6 158055182 1055182             
#7 193991176 1991176             
#8 147845896 1845896             
#9 177083273 1083273             
#10 129086338 1086338  

你做错了。您正在捕获组而不是提取这些组。使用 gsub 等字符串替换函数,在 pattern 参数中使用捕获组,在 replacement argument 中使用 groups reference,您将获得所需的结果

strings <- c('12233333', '23345678', '00123456')
gsub('(\d{1})(\d{2})(\d{5})', '\1\3', strings)

[1] "133333" "245678" "023456"

我想你要找的是str_replace,而不是str_extract(感谢@AnilGoyal 的虚拟数据),即

> str_replace(strings, "(\d{1})(\d{2})(\d{5})", "\1\3")
[1] "133333" "245678" "023456"

既然位置是固定的,为什么不使用子字符串或类似函数而不是正则表达式来提取字符串?它们通常比正则表达式提取更快。

library(dplyr)
library(stringr)

d %>% mutate(res = str_c(str_sub(a, 1, 1), str_sub(a, 4, 9)))

#.          a     res
#1  103016397 1016397
#2  164356395 1356395
#3  134615352 1615352
#4  176581897 1581897
#5  127035705 1035705
#6  158055182 1055182
#7  193991176 1991176
#8  147845896 1845896
#9  177083273 1083273
#10 129086338 1086338

或以 R 为基数 -

transform(d, res = paste0(substr(a, 1, 1), substr(a, 4, 9)))