Skip to content
Guides

搜索文本并提取范围内容

阅读器中的文本处理通常包含两类任务:

  1. 在整份文档中搜索关键字,并定位命中结果。
  2. 在指定页面范围内提取文本内容,用于摘要、预览或二次处理。

本页同时说明这两类能力,但两者的用途并不相同:

  • 关键字搜索关注“查找命中结果并导航到结果位置”。
  • 范围文本提取关注“从指定区域读取文本内容”。

如果目标是获取阅读器中手动选中的文本内容,应查看 获取选中内容

在整份文档中搜索关键字

关键字搜索通常用于以下场景:

  • 在长文档中定位指定术语。
  • 构建搜索结果列表。
  • 将搜索结果高亮到当前阅读视图中。

创建搜索器并遍历页面

搜索流程通常包括以下步骤:

  1. 创建搜索结果集合。
  2. 获取 ITextSearcher
  3. 设置关键字和搜索选项。
  4. 遍历页面并保存命中结果。
java
List<CPDFTextRange> searchTextInfoList = new ArrayList<>();
ITextSearcher textSearcher = readerView.getTextSearcher();

String keywords = "ComPDF";
textSearcher.setSearchConfig(
    keywords,
    CPDFTextSearcher.PDFSearchOptions.PDFSearchCaseSensitive
);

for (int i = 0; i < document.getPageCount(); i++) {
    CPDFPage page = document.pageAtIndex(i);
    CPDFTextPage textPage = page.getTextPage();
    if (textPage == null || !textPage.isValid()) {
        continue;
    }

    List<CPDFTextRange> searchPageContent = textSearcher.searchKeyword(i);
    if (!searchPageContent.isEmpty()) {
        searchTextInfoList.addAll(searchPageContent);
    }
}
kotlin
val searchTextInfoList = mutableListOf<CPDFTextRange>()
val textSearcher: ITextSearcher = readerView.getTextSearcher()

val keywords = "ComPDF"
textSearcher.setSearchConfig(
    keywords,
    CPDFTextSearcher.PDFSearchOptions.PDFSearchCaseSensitive
)

for (i in 0 until document.pageCount) {
    val page = document.pageAtIndex(i)
    val textPage = page.textPage
    if (textPage == null || !textPage.isValid) {
        continue
    }

    val searchPageContent = textSearcher.searchKeyword(i)
    if (searchPageContent.isNotEmpty()) {
        searchTextInfoList.addAll(searchPageContent)
    }
}

选择搜索选项

setSearchConfig(...) 支持以下常见选项:

选项说明
PDFSearchCaseInsensitive大小写不敏感0
PDFSearchCaseSensitive大小写敏感1
PDFSearchMatchWholeWord匹配整个单词2

搜索选项应根据业务目标选择。例如,全文检索通常适合大小写不敏感搜索,术语精确匹配则更适合大小写敏感或整词匹配。

读取命中结果文本和上下文

如果页面需要展示搜索摘要、片段预览或上下文命中内容,可以继续从 CPDFTextRange 中提取文本。

以下示例展示如何读取命中文本和前后上下文。

java
int pageIndex = 0;
List<CPDFTextRange> searchPageContent = textSearcher.searchKeyword(pageIndex);
if (searchPageContent.isEmpty()) {
    return;
}

CPDFTextRange textRange = searchPageContent.get(0);
CPDFPage page = document.pageAtIndex(pageIndex);
CPDFTextPage textPage = page.getTextPage();
String text = textPage.getText(textRange);

int targetStart = textRange.location - 20;
int length;
if (targetStart > 0) {
    length = textRange.length + 40;
} else {
    length = textRange.length + 40 + targetStart;
    targetStart = 0;
}

CPDFTextRange targetTextRange = new CPDFTextRange(targetStart, length);
String contextText = textPage.getText(targetTextRange);

在处理单页结果时,应确保 CPDFTextRange 与当前页面的 CPDFTextPage 对应,避免跨页错误读取。

高亮并切换搜索结果

当搜索结果需要在阅读器中高亮显示时,可以使用以下方法:

高亮指定结果

java
int pageIndex = 0;
int textRangeIndex = 0;
textSearcher.searchBegin(pageIndex, textRangeIndex);
readerView.invalidateAllChildren();

跳转到上一个结果

java
textSearcher.searchBackward();

跳转到下一个结果

java
textSearcher.searchForward();

结束当前搜索流程

java
textSearcher.cancelSearch();

按页面范围提取文本内容

除了关键字搜索,CPDFPageCPDFTextPage 也支持按矩形范围提取文本。这个能力适合用于:

  • 页面摘要提取。
  • 自定义内容分析。
  • 固定区域文本读取。

下面的示例先定义页面坐标中的矩形区域,再转换为当前页面可用于文本提取的坐标范围。

java
CPDFPage pdfPage = document.pageAtIndex(0);
CPDFTextPage pdfTextPage = pdfPage.getTextPage();

RectF selectRect = new RectF(0f, 0f, 500f, 500f);
selectRect = pdfPage.convertRectFromPage(
    false,
    pdfPage.getSize().width(),
    pdfPage.getSize().height(),
    selectRect
);

CPDFTextSelection[] textSelectionArr = pdfTextPage.getSelectionsByLineForRect(selectRect);

for (CPDFTextSelection textSelection : textSelectionArr) {
    if (textSelection == null) {
        continue;
    }

    String text = pdfTextPage.getText(textSelection.getTextRange());
}
kotlin
val pdfPage = document.pageAtIndex(0)
val pdfTextPage = pdfPage.textPage

var selectRect = pdfPage.convertRectFromPage(
    false,
    pdfPage.size.width(),
    pdfPage.size.height(),
    RectF(0f, 0f, 500f, 500f)
)

val textSelectionArr = pdfTextPage.getSelectionsByLineForRect(selectRect)

for (textSelection in textSelectionArr) {
    val text = pdfTextPage.getText(textSelection.textRange)
}

这里提取的是指定矩形范围内的文本,不等同于阅读器中通过长按产生的手动选中结果。

使用搜索和范围提取时的注意事项

  • 全文搜索适合定位关键字,范围提取适合读取指定区域文本,两者不应混用为同一种能力。
  • 读取搜索结果前,建议先判断结果集合是否为空。
  • 如果页面要展示搜索命中列表,通常应先保存 pageIndexCPDFTextRange 的对应关系。
  • 如果页面目标是获取用户在阅读器中手动框选或长按选中的文本,应查看 获取选中内容

相关章节