【问题标题】:regex grouping and re-ordering正则表达式分组和重新排序
【发布时间】:2021-08-15 11:21:18
【问题描述】:

恐怕我有一个正则表达式问题。我想提取字符串的第一组,即 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  

【问题讨论】:

    标签: r regex tidyverse stringr


    【解决方案1】:

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

    strings <- c('12233333', '23345678', '00123456')
    gsub('(\\d{1})(\\d{2})(\\d{5})', '\\1\\3', strings)
    
    [1] "133333" "245678" "023456"
    

    【讨论】:

    • gsub 回答,点赞!或者我们可以使用gsub("(?&lt;=^\\d{1})\\d{2}", "", strings, perl = TRUE)
    • 是的,这样我们就不用替换第 2 位和第 3 位数字并使用环视。实际上可以有很多方法来处理正则表达式。但是在这里 OP 达到了一定程度,并且难以理解捕获组将如何工作,所以我选择了这个。感谢您的支持 :) 我已经投票给你了
    【解决方案2】:

    我认为您正在寻找的是str_replace,而不是str_extract(感谢@AnilGoyal 的虚拟数据),即,

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

    【讨论】:

      【解决方案3】:

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

      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)))
      

      【讨论】:

        猜你喜欢
        • 2021-12-24
        • 1970-01-01
        • 2021-12-03
        • 1970-01-01
        • 2012-12-18
        • 1970-01-01
        • 2015-10-22
        • 2019-01-25
        • 1970-01-01
        相关资源
        最近更新 更多