【发布时间】:2019-11-18 10:31:05
【问题描述】:
VB2017 使用 iText7。我正在寻找一种在 PDF 中搜索关键文本的方法。当我找到关键文本时,我想返回它所在的框中的所有文本。
例如,在此 PDF 中,我查找关键短语“可用长度”,并希望在找到它的框中返回文本“Rwy 33 PAPI-L,可用长度,注释。”
这是我目前所拥有的 (based on this),希望对这个概念有任何建议或建议:
Public Function FindTextInPdfFile(ByVal fileName As String, ByVal searchText As String, ByVal IsCaseSensitive As Boolean) As List(Of String)
'basic checks
If String.IsNullOrWhiteSpace(fileName) Then Return Nothing
If String.IsNullOrWhiteSpace(searchText) Then Return Nothing
If Not File.Exists(fileName) Then Return Nothing
'setup the regex to use or not use case sensitivity in the match
Dim pattern As String = String.Format("({0})", searchText)
Dim regEx As Regex = Nothing
If IsCaseSensitive Then
regEx = New Regex(pattern)
Else
regEx = New Regex(pattern, RegexOptions.IgnoreCase)
End If
'setup the extraction strategy and temp buffer
Dim strategy As ITextExtractionStrategy = New SimpleTextExtractionStrategy
Dim buffBasic As New StringBuilder
'open the PDF and do a basic search for the text in each page. for each page where we detect the search item
'we will add that to the temp buffer.
Using pdfReader As PdfReader = New PdfReader(fileName)
Using pdfDocument As PdfDocument = New PdfDocument(pdfReader)
For pageNum As Integer = 1 To pdfDocument.GetNumberOfPages
Dim page As PdfPage = pdfDocument.GetPage(pageNum)
Dim currentPageText As String = PdfTextExtractor.GetTextFromPage(page, strategy)
If regEx.Matches(currentPageText).Count > 0 Then
'Debug.Print("found search text [{0}] in page num {1}", searchText, pageNum)
'Debug.Print("GetResultantText={0}", strategy.GetResultantText)
'GetResultantText has lines of text separated by an LF
buffBasic.Append(strategy.GetResultantText & lf)
End If
Next pageNum
End Using
End Using
'the buffer should have lines of text separated by an LF
Dim linesBasic As List(Of String) = buffBasic.ToString.Split(lf).ToList
Dim linesMatch As List(Of String) = linesBasic.FindAll(Function(x) regEx.Matches(x).Count > 0)
Debug.Print("match count={0}", linesMatch.Count)
For Each line In linesMatch
Debug.Print("line={0}", line)
Next line
Return linesMatch
End Function
在示例 PDF 上测试此结果
FindTextInPdfFile(pdf, "usable length", True)
match count=1
line=Rwy 33 PAPI-L, usable length, notes.
【问题讨论】:
-
盒子是如何创建的?周围有火线吗?还是细长方形?还是位图图像背景?如果您不确定,请分享一个具有代表性的示例 pdf。你是指细线的盒子还是粗线的单元格?
-
显示的方框仅用于演示。当我在 Acrobat Pro 中打开 PDF 时,我可以选择“编辑”>“编辑文本和图像”,然后在文本框周围绘制框。这些编辑框由细线框表示。
-
好的,所以这些框通常不在 PDF 中可见...但是它们是什么?它们是文本对象吗?剪辑路径?完全不同的东西?如果不确定,请分享一个有代表性的例子pdf。
-
它们只是文本对象。
-
在这种情况下,扩展
SimpleTextExtractionStrategy(您在代码中使用)以监听BEGIN_TEXT和END_TEXT事件类型就足够了。如果发生此类事件,扩展程序可能会在文本中添加特定标记(使用appendTextChunk)。或者您甚至可以将文本拆分为一组文本(每个文本代表一个文本对象)。