【问题标题】:How to extract a specific instance of a string of digits after a specific character using regex如何使用正则表达式在特定字符之后提取一串数字的特定实例
【发布时间】:2021-06-29 03:47:23
【问题描述】:

标题可能令人困惑,所以请允许我详细说明一下,假设我已经初始化了以下字符串

some_string_1 <- "Charges: $400.50 applied to account 1, $300.70 applied to account 2, $120.30 applied to account 3"

some_string_2 <- "Charges: $500.50 applied to account 2, $200.10 applied to account 3, $150.90 applied to account 1"

假设我只关注账户 1,所以我想提取与账户 1 的费用相关的美元符号之后的数字。我想知道如何使用正则表达式和 str_extract 等函数,我可以获得以下信息输出:

假设我打电话给str_extract(some_string_1, regexp),我想给它

[1] "400.50"

假设我打电话给str_extract(some_string_2, regexp),我希望它给

[1] "150.90"

如您所见,帐户 1 的费用在两个字符串中的不同位置(它是字符串 1 中列出的第一个费用,但字符串 2 中列出的第三个费用),因此正则表达式必须考虑到这一点。

到目前为止,我所拥有的只有以下内容:regexp &lt;- "(?&lt;=\\$)\\d+(?=.)",它成功地给了我出现在字符串中的第一个美元符号之后的数字(没有小数位的数字),但我不知道如何指定我只想要与帐户 1 上应用的费用相关联的美元符号后面的数字。在这方面寻求帮助。

【问题讨论】:

    标签: r regex


    【解决方案1】:

    不是您正在寻找的正则表达式答案 -

    vec <- c(some_string_1, some_string_2)
    
    sapply(strsplit(vec, ',\\s*'), function(x) 
      sub('.*\\$(\\d+\\.\\d+).*', '\\1', x[grep('account 1', x)]))
    
    #[1] "400.50" "150.90"
    

    这里的逻辑是将每个帐户拆分为单独的向量并从'account 1'中提取数字。

    【讨论】:

    • 有趣,这绝对有效。不过出于好奇,您认为使用正则表达式可以实现这样的事情吗?
    • 这绝对是可能的。不过我现在想不通。
    【解决方案2】:

    这是解决您问题的一种方法。我不使用r,所以我无法为您提供任何代码。


    正则表达式

    (\$\d+(?:\.\d+)?)[^,\"]*account [#{range}]
    

    其中#{range} 可以是1-12-3 等等。您感兴趣的部分将在比赛的第1组中获得。请注意,必须应用正则表达式全局才能找到所有匹配项。


    输出

    #{range} = 1-1
    
    match 1:                                 match 2:
    $400.50 applied to account 1             $150.90 applied to account 1
    group-1:                                 group-1:
    $400.50                                  $150.90
    
    
    #{range} = 2-3
    
    match 1:                                 match 2:
    $300.70 applied to account 2             $120.30 applied to account 3
    group-1:                                 group-1:
    $300.70                                  $120.30
    
    match 3:                                 match 4:
    $500.50 applied to account 2             $200.10 applied to account 3
    group-1:                                 group-1:
    $500.50                                  $200.10
    

    测试链接: https://regex101.com/r/w3VY4I/1


    如果您遇到任何其他问题,请发表评论。

    【讨论】:

      【解决方案3】:

      您也可以使用以下策略将这些字符串转换为排列整齐的数据

      library(tidyverse)
      
      some_string_1 <- "Charges: $400.50 applied to account 1, $300.70 applied to account 2, $120.30 applied to account 3"
      
      some_string_2 <- "Charges: $500.50 applied to account 2, $200.10 applied to account 3, $150.90 applied to account 1"
      
      c(some_string_1, some_string_2) %>% as.data.frame() %>%
        setNames('Strings') %>%
        mutate(ID = row_number()) %>%
        separate_rows(Strings, sep = ', ') %>%
        extract(Strings, into = c('Amt', 'Account'), regex = '\\$(\\d+\\.\\d*).*(account \\d+)') %>%
        pivot_wider(names_from = Account, values_from = Amt)
      
      #> # A tibble: 2 x 4
      #>      ID `account 1` `account 2` `account 3`
      #>   <int> <chr>       <chr>       <chr>      
      #> 1     1 400.50      300.70      120.30     
      #> 2     2 150.90      500.50      200.10
      

      pivot_wider 中使用values_fn = as.numeric 参数将同时将字符值转换为数字,这可能有助于进一步分析。

      【讨论】:

        【解决方案4】:

        仅使用stringr::str_extract 的方法可能是:

        stringr::str_extract(some_string_1, "(?<=\\$)\\d*\\.?\\d*(?=[^$]*account 1)")
        #[1] "400.50"
        
        stringr::str_extract(some_string_2, "(?<=\\$)\\d*\\.?\\d*(?=[^$]*account 1)")
        #[1] "150.90"
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-08-04
          • 1970-01-01
          • 2017-12-13
          • 2018-11-15
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多