【问题标题】:In R, how do I match markdown list在 R 中,我如何匹配降价列表
【发布时间】:2015-07-12 23:05:02
【问题描述】:

我正在尝试匹配以下有序和无序列表并提取项目符号/列表点。

library(stringr)
examples <- c(
"* Bullet 1\n* Bullet 2\n* Bullet 3",
"1. Bullet 1\n2. Bullet 2\n3. Bullet 3",
"* This is a test 1\n* This is a test with some *formatting*\n* This is a test with different _formatting_"
)

我想做的是:

  1. 以编程方式识别它是一个列表
  2. 仅将每个解析为列表项的文本

结果是

some_str_fun(example,pattern) # or multiples
"Bullet 1" "Bullet 2" "Bullet 3"
"Bullet 1" "Bullet 2" "Bullet 3"
"This is a test 1" "This is a test with some *formatting*" 
"This is a test with different _formatting_"

我一直在使用以下模式和 str_extract/match,但似乎找不到完全实用的东西

[*]+\\s(.*?)[\n]* # for * Bullet X\n
[1-9]+[.]\\s(.*?)[\n]* # for 1. Bullet X\n

我在这些模式上尝试了很多不同的迭代,但似乎无法完全得到我想要的。

【问题讨论】:

  • 是否可以有一个“0”:例如10. Bullet?
  • @Frank 不,我不这么认为。

标签: regex r stringr


【解决方案1】:

您可以使用gsubfn 包中的strapply 来匹配整个模式。

library(gsubfn)

examples <- c(
    "* Bullet 1\n* Bullet 2\n* Bullet 3",
    "1. Bullet 1\n2. Bullet 2\n3. Bullet 3",
    "* This is a test 1\n* This is a test with some *formatting*\n* This is a test with different _formatting_"
)

strapply(examples, '(?:\\*|\\d+\\.) *([^\n]+)', c, simplify = c)

# [1] "Bullet 1"                                  
# [2] "Bullet 2"                                  
# [3] "Bullet 3"                                  
# [4] "Bullet 1"                                  
# [5] "Bullet 2"                                  
# [6] "Bullet 3"                                  
# [7] "This is a test 1"                          
# [8] "This is a test with some *formatting*"     
# [9] "This is a test with different _formatting_"

【讨论】:

    【解决方案2】:

    这是一种不同的方法,但如果您将 markdown 呈现为 HTML,您可以使用一些现有的提取方法来做您想做的事情:

    library(stringr)
    
    examples <- c(
    "* Bullet 1\n* Bullet 2\n* Bullet 3",
    "1. Bullet 1\n2. Bullet 2\n3. Bullet 3",
    "* This is a test 1\n* This is a test with some *formatting*\n* This is a test with different _formatting_"
    )
    
    extract_md_list <- function(md_text) {
    
      require(rvest)
      require(rmarkdown)
    
      fil_md <- tempfile()
      fil_html <- tempfile()
      writeLines(md_text, con=fil_md)
    
      render(fil_md, output_format="html_document", output_file=fil_html, quiet=TRUE)
    
      pg <- html(fil_html)
      ret <- html_nodes(pg, "li") %>% html_text()
    
      # cleanup
      unlink(fil_md)
      unlink(fil_html)
    
      return(ret)
    
    }
    
    extract_md_list(examples)
    
    ## [1] "Bullet 1"                                
    ## [2] "Bullet 2"                                
    ## [3] "Bullet 3"                                
    ## [4] "Bullet 1"                                
    ## [5] "Bullet 2"                                
    ## [6] "Bullet 3"                                
    ## [7] "This is a test 1"                        
    ## [8] "This is a test with some formatting"     
    ## [9] "This is a test with different formatting"
    

    【讨论】:

    • 我喜欢这个。但我已经直接从 Rmd 编​​码了其余部分(粗斜体、绘图、内联 R)。
    • 那里 is 存在pandoc 的原因,但是如果您对正则表达式非常执着,那么您应该能够使用gist.github.com/jbroadway/2836900 的元素来提取您的内容需要。不过,这又快又干净。
    • Pandoc 无法运行 R 代码。或者至少,不是我所知道的。
    【解决方案3】:

    这是另一种选择。如果需要,您可以使用 unlist 换行:

    str_extract_all(examples, "[^*1-9\n ]\\w+( ?[\\w*]+)*")
    # or 
    #str_extract_all(examples, "[^*1-9\n ]\\w+( ?[a-zA-Z0-9_*]+)*")
    
    #[[1]]
    #[1] "Bullet 1" "Bullet 2" "Bullet 3"
    #
    #[[2]]
    #[1] "Bullet 1" "Bullet 2" "Bullet 3"
    #
    #[[3]]
    #[1] "This is a test 1"                          
    #[2] "This is a test with some *formatting*"     
    #[3] "This is a test with different _formatting_"
    

    还有其他几个选项,特别是如果您不关心在单个正则表达式或单行代码中获取所有内容。这是另一种方法。正则表达式更简单,但您最终会得到"",这需要额外的一行:

    splits <- unlist(str_split(examples, "\n|\\d+\\. |\\* "))
    splits[splits != ""]
    #[1] "Bullet 1"                                  
    #[2] "Bullet 2"                                  
    #[3] "Bullet 3"                                  
    #[4] "Bullet 1"                                  
    #[5] "Bullet 2"                                  
    #[6] "Bullet 3"                                  
    #[7] "This is a test 1"                          
    #[8] "This is a test with some *formatting*"     
    #[9] "This is a test with different _formatting_"
    

    【讨论】:

    • 前几个项目符号中的尾随数字会发生什么变化?
    • 所写的正则表达式与您假设的不匹配。
    • 您将初始部分包装在否定字符类中,您不能在类中使用分组构造。
    猜你喜欢
    • 1970-01-01
    • 2013-11-25
    • 2019-01-12
    • 2019-03-25
    • 1970-01-01
    • 1970-01-01
    • 2016-10-22
    • 1970-01-01
    • 2021-10-05
    相关资源
    最近更新 更多