【问题标题】:Extracting pattern from the nested list in R using regex使用正则表达式从 R 中的嵌套列表中提取模式
【发布时间】:2016-08-05 20:41:22
【问题描述】:

我有以下时间段的排序列表 (lst),我想将时间段拆分为特定日期,然后在不改变列表顺序的情况下提取最大时间段。

$`1`
[1] "01.12.2015 - 21.12.2015"

$`2`
[1] "22.12.2015 - 05.01.2016"

$`3`
[1] "14.09.2015 - 12.10.2015" "29.09.2015 - 26.10.2015"

因此,调整后的列表应该是这样的:

$`1`
[1] "01.12.2015" "21.12.2015"

$`2`
[1] "22.12.2015"  "05.01.2016" 

$`3`
[1] "14.09.2015"  "12.10.2015" "29.09.2015"  "26.10.2015"

为了做到这一点,我开始拆分列表:

   lst_split <- str_split(lst, pattern = " - ")

导致以下结果:

[[1]]
[1] "01.12.2015" "21.12.2015"

[[2]]
[1] "22.12.2015" "05.01.2016"

[[3]]
[1] "c(\"14.09.2015"             "12.10.2015\", \"29.09.2015" "26.10.2015\")"  

然后,我尝试提取模式:

lapply(lst_split, function(x) str_extract(pattern = c("\\d+\\.\\d+\\.\\d+"),x))

但我的输出缺少一个日期 (29.09.2015)

[[1]]
[1] "01.12.2015" "21.12.2015"

[[2]]
[1] "22.12.2015" "05.01.2016"

[[3]]
[1] "14.09.2015" "12.10.2015" "26.10.2015"

有没有人知道我该如何让它发挥作用并提出更有效的解决方案?提前谢谢你。

【问题讨论】:

  • 您错过的日期是由于str_extract - 使用str_extract_all
  • 不确定为什么需要`str_extract,因为你需要获得最大日期。
  • @WiktorStribiżew,谢谢它的工作,但导致多级列表不太容易操作,我想避免它。
  • @WiktorStribiżew 和 @akun 谢谢!现在我明白了,通过结合你的 cmets 就足以使用str_extract_all(lst, "\\d+\\.\\d+\\.\\d+") 并忽略我的下一步与str_extract
  • 甚至&gt; lst_split &lt;- str_split(lst, pattern = " - ") &gt; l &lt;- str_extract_all(lst_split, "\\d+\\.\\d+\\.\\d+") &gt; j &lt;- sapply(l,paste,collapse=";") &gt; k = str_extract_all(j, "[^;]+;[^;]+") &gt; unlist(k)

标签: regex r lapply


【解决方案1】:

感谢@WiktorStribiżew 和@akrun 的cmets,使用str_extract_all 就足够了。

在这个例子中:

> str_extract_all(lst,"\\d+\\.\\d+\\.\\d+")
[[1]]
[1] "01.12.2015" "21.12.2015"

[[2]]
[1] "22.12.2015" "05.01.2016"

[[3]]
[1] "14.09.2015" "12.10.2015" "29.09.2015" "26.10.2015"

【讨论】:

    【解决方案2】:

    1) 使用strsplit,使用unlist 展平每个组件,将日期转换为"Date" 类,然后使用range 以获得最大时间跨度。没有使用任何包。

    > lapply(lst, function(x) range(as.Date(unlist(strsplit(x, " - ")), "%d.%m.%Y")))
    $`1`
    [1] "2015-12-01" "2015-12-21"
    
    $`2`
    [1] "2015-12-22" "2016-01-05"
    
    $`3`
    [1] "2015-09-14" "2015-10-26"
    

    2) 这种使用 magrittr 管道的变体也可以:

    library(magrittr)
    lapply(lst, function(x) 
       x %>% 
         strsplit(" - ") %>% 
         unlist %>% 
         as.Date("%d.%m.%Y") %>% 
         range
    )
    

    注意:可重现形式的输入lst 是:

    lst <- structure(list(`1` = "01.12.2015 - 21.12.2015", `2` = "22.12.2015 - 05.01.2016", 
    `3` = c("14.09.2015 - 12.10.2015", "29.09.2015 - 26.10.2015"
    )), .Names = c("1", "2", "3"))
    

    【讨论】:

    • 谢谢@G。格洛腾迪克,您的代码完全符合我的目标,只需一行代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-21
    • 2018-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-29
    相关资源
    最近更新 更多