【问题标题】:Check for multiple words in string match for text search in r检查字符串匹配中的多个单词以在 r 中进行文本搜索
【发布时间】:2017-09-27 19:25:28
【问题描述】:

目前我有一个代码可用于一个单词搜索,我们可以搜索多个单词并将这些匹配的单词写入数据框中吗? (为了澄清,请参阅此post)这是akrun's 解决方案,适用于一个词。 代码如下:

 library(pdftools)
 library(tesseract)

 All_files <- Sys.glob("*.pdf")
 v1     <- numeric(length(All_files))
 word   <- "school"
 df     <- data.frame()
 Status <- "Present"

for (i in seq_along(All_files)){
  file_name <- All_files[i]

  cnt <- pdf_info(All_files[i])$pages
  print(cnt)
  for(j in seq_len(cnt)){
      img_file <- pdftools::pdf_convert(All_files[i], format = 'tiff', pages = j, dpi = 400)
      text     <- ocr(img_file)
      ocr_text <- capture.output(cat(text))
      check    <- sapply(ocr_text, paste, collapse="")
      junk     <- dir(path= paste0(path, "/tiff"), pattern="tiff")
      file.remove(junk)
      br <-if(length(which(stri_detect_fixed(tolower(check),tolower(word)))) <= 0) "Not Present"  
              else "Present" 
      print(br)       
      if(br=="Present") {
         v1[i] <- j
         break}
    }

    Status <- if(v1[i] == 0) "Not Present" else "Present"
    pages  <- if(v1[i] == 0) "-" else 
      paste0(tools::file_path_sans_ext(basename(file_name)), "_", v1[i])
    words  <- if(v1[i] == 0) "-" else word
    df     <- rbind(df, cbind(file_name = basename(file_name),
                    Status, pages = pages, words = words))
}

这里我们只搜索一个词,即school。我们可以搜索多个单词,如schoolgymswimming pool

预期 O/P

fileName   Status        Page             Words                    TEXT
test.pdf   Present     test_1             gym            I go gym regularly  
test.pdf   Present     test_3             school     Here is the next school
test1.pdf  Present     test1_4            swimming pool  In swimming pool
test1.pdf  Present     test1_7            gym         next to Gold gym
test2.pdf  Not Present    -               -

文件名=文件名

状态=如果找到任何单词,则“存在”,否则“不存在”

Page=这里“_1”、“_3”定义了找到单词的页码;;在“test_1”页找到了“gym”一词,在“test_3”页找到了“school”。

单词=找到所有单词;;就像在 test.pdf 文件的第 1 页和第 3 页上只找到“健身房”和“学校”,在 test1.pdf 文件的第 4 页和第 7 页上只找到“游泳池”和“健身房”。

TEXT = 找到该词的文本

对此的任何建议都会有所帮助。

谢谢

【问题讨论】:

  • 检查 grepl() 并使用类似“(word|gym|swimming pool)”的东西作为模式。它将返回 TRUE 或 FALSE,具体取决于您的单词是否存在。我可以稍后在我的电脑上查看它
  • ifelse(grepl("Swimming|Hanging", check), "Present", "Not Present").. 这将返回存在或不存在,但仍无法在数据框中附加那些匹配的单词。
  • 要提取匹配的单词,请查看stringrstr_extract_all。您必须进行一些进一步的清理才能将唯一的单词粘贴在一起并将它们附加到您的 data.frame

标签: r search dataframe ocr


【解决方案1】:

您使用外部循环浏览目录中的每个 PDF。然后您浏览 PDF 的所有页面并提取内部循环中的文本。您想检查每个文档是否至少有一页包含schoolgymswimming pool。您要使用的返回值是:

  1. 包含PresentNot present 的PDF 文档数量的长度向量。
  2. 带有一些字符串的三个向量,包含有关哪个单词出现在何时何地的信息。

对吗?

您可以跳过循环中的几个步骤,尤其是在将 PDF 转换为 TIFF 并使用 ocr 从中读取文本时:

all_files <- Sys.glob("*.pdf")
strings   <- c("school", "gym", "swimming pool")

# Read text from pdfs
texts <- lapply(all_files, function(x){
                img_file <- pdf_convert(x, format="tiff", dpi=400)
                return( tolower(ocr(img_file)) )
                })

# Check for presence of each word in checkthese
pages <- words <- vector("list", length(texts))
for(d in seq_along(texts)){
  for(w in seq_along(strings)){
    intermed   <- grep(strings[w], texts[[d]])
    words[[d]] <- c(words[[d]], 
                    strings[w][ (length(intermed) > 0) ])
    pages[[d]] <- unique(c(pages[[d]], intermed))
  }
}

# Organize data so that it suits your wanted output
fileName <- tools::file_path_sans_ext(basename(all_files))

Page <- Map(paste0, fileName, "_", pages, collapse=", ")
Page[!grepl(",", Page)] <- "-"
Page <- t(data.frame(Page))

Words    <- sapply(words, paste0, collapse=", ")
Status   <- ifelse(sapply(Words, nchar) > 0, "Present", "Not present")

data.frame(row.names=fileName, Status=Status, Page=Page, Words=Words)        
#       Status                                   Page                      Words
# pdf1 Present                         pdf1_1, pdf1_2         gym, swimming pool
# pdf2 Present pdf2_2, pdf2_5, pdf2_8, pdf2_3, pdf2_6 school, gym, swimming pool

它不像我希望的那样可读。可能是因为对 w.r.t 的要求很少。输出需要一些小的中间步骤,这会使代码看起来有点混乱。不过效果不错

【讨论】:

  • yes 对于每个 pdf,我在该 pdf 的每一页中搜索一些预定义的单词,如果在该 pdf 页面上找到任何这些单词,则捕获从文本中匹配的单词并附加页面找到它的编号(或页面),并在数据框中附加与文本匹配的单词......
  • 但是对于存在任何单词的每个文件,它都会在“单词”列中附加所有(在我们的例子中为 3 个单词)单词。相反,我希望只附加匹配的那个单词。您的代码附加了数据框中的所有 3 个单词。像“学校”这个词在第一个pdf中没有找到,但它仍然在“学校”后面加上“健身房”和“游泳池”。
  • 对于page 列,我期待找到单词的页码,但如果找到该单词,您的代码会将文件名粘贴为“_ present”。
  • 我认为如果您的问题涉及想要的输出,那就太好了。像这样,你在做什么似乎很清楚,但实际上这里和那里有 5 处调整,回答者只有在回答你实际提出的问题后才会听到。我稍后会更新答案
  • 已用预期的答案(数据框)更新了帖子。请检查一下
猜你喜欢
  • 2015-07-25
  • 2018-04-09
  • 1970-01-01
  • 2019-11-03
  • 1970-01-01
  • 1970-01-01
  • 2021-03-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多