Java 查找并高亮 Word 文字:精确查找及正则表达式模糊查找

最近在处理一批 Word 报告时,遇到了一个需求:把文档中涉及"风险"的文字标记出来,方便后续检查。

如果只是查找一个词,可以使用 Word 自带的查找功能。但实际处理时,需求可能更具体,比如只标记第一次出现的关键词、标记所有匹配位置,或者一次匹配"风险评估""风险分析""风险排查"等不同表述。

本文记录如何使用 Spire.Doc for Java 实现这几种文本查找和高亮操作。

一、准备环境

使用 Maven 项目时,可以在 ​​pom.xml​​ 中添加以下配置:

xml 复制代码
<repositories>
    <repository>
        <id>com.e-iceblue</id>
        <name>e-iceblue</name>
        <url>https://repo.e-iceblue.cn/repository/maven-public/</url>
    </repository>
</repositories>

<dependencies>
    <dependency>
        <groupId>e-iceblue</groupId>
        <artifactId>spire.doc</artifactId>
        <version>14.9.5</version>
    </dependency>
</dependencies>

这里使用 ​​14.9.5​​ 版本作为示例,并非要求必须使用最新版本。

准备一个名为 ​​input.docx​​ 的 Word 文档,内容如下:

项目风险需要提前识别。

本周完成风险评估,下周开始风险排查。

风险分析结果需要记录。

其他部门的风险评估也要跟进。

下面分别处理首次匹配、全部匹配和正则表达式匹配。

二、只高亮第一次出现的关键词

如果只需要标记文档中第一次出现的"风险",可以使用 ​​Document.findString()​​ 方法。

typescript 复制代码
import com.spire.doc.Document;
import com.spire.doc.FileFormat;
import com.spire.doc.documents.TextSelection;

import java.awt.Color;

public class HighlightFirstOccurrence {

    public static void main(String[] args) {

        // 加载 Word 文档
        Document document = new Document();
        try {
            document.loadFromFile("input.docx");

            // 查找第一次出现的关键词
            TextSelection selection =
                    document.findString("风险", false, false);

            // 设置匹配文本的高亮颜色
            if (selection != null) {
                selection.getAsOneRange()
                        .getCharacterFormat()
                        .setHighlightColor(Color.YELLOW);
            }

            // 保存 Word 文档
            document.saveToFile(
                    "HighlightFirst.docx", FileFormat.Docx_2013);

        } finally {
            document.dispose();
        }
    }
}

​​findString()​​ 的两个布尔参数分别表示是否区分大小写,以及是否只匹配完整单词。该方法返回一个 ​​TextSelection​​ 对象,因此只会对找到的第一个匹配结果设置高亮。对于示例文档,第一句中的"风险"会被标记为黄色,后面出现的相同文字则保持不变。

另外,代码检查了匹配结果是否为 ​​null​​,避免关键词不存在时出现空指针异常。

三、高亮所有匹配的关键词

如果需要标记整个文档中的所有"风险",可以将 ​​findString()​​ 换成 ​​findAllString()​​。

typescript 复制代码
import com.spire.doc.Document;
import com.spire.doc.FileFormat;
import com.spire.doc.documents.TextSelection;

import java.awt.Color;

public class HighlightAllOccurrences {

    public static void main(String[] args) {

        // 加载 Word 文档
        Document document = new Document();
        try {
            document.loadFromFile("input.docx");

            // 查找所有匹配的关键词
            TextSelection[] selections =
                    document.findAllString("风险", false, false);

            // 遍历匹配结果并设置高亮
            if (selections != null) {
                for (TextSelection selection : selections) {
                    selection.getAsOneRange()
                            .getCharacterFormat()
                            .setHighlightColor(Color.YELLOW);
                }
            }

            // 保存 Word 文档
            document.saveToFile(
                    "HighlightAll.docx", FileFormat.Docx_2013);

        } finally {
            document.dispose();
        }
    }
}

两者最大的区别在于返回值:

  • ​findString()​ 返回一个 TextSelection,用于处理首次匹配。
  • ​findAllString()​ 返回一个 TextSelection[],用于处理全部匹配。

示例文档中的"风险"共出现 5 次,因此使用 ​​findAllString()​​ 时,这 5 处文字都会被高亮。

这里通过 ​​getAsOneRange()​​ 获取匹配的文本范围,再使用 ​​getCharacterFormat().setHighlightColor()​​ 设置黄色高亮。

这种操作修改的是匹配文字的高亮格式,而不是将所在段落整体设置为黄色。

四、使用正则表达式进行灵活匹配

前面两种方法都适合搜索固定字符串。不过,当需要查找的文字存在一定变化时,正则表达式会更方便。

例如,我们希望同时高亮以下三种表述:

  • 风险评估
  • 风险分析
  • 风险排查

并且允许"风险"和后面的词之间存在空格。

可以使用下面的正则表达式:

ini 复制代码
Pattern pattern = Pattern.compile(
        "风险\s*(评估|分析|排查)");

其中:

​​风险​​ 表示固定匹配这两个汉字。

​​\s*​​ 表示允许出现零个或多个空白字符。在 Java 字符串中,反斜杠需要转义。

​​(评估|分析|排查)​​ 表示匹配三个选项中的任意一个。

1. 高亮第一个正则匹配结果

如果只需要处理第一个符合模式的文本,可以使用 ​​findPattern()​​:

java 复制代码
import com.spire.doc.Document;
import com.spire.doc.FileFormat;
import com.spire.doc.documents.TextSelection;

import java.awt.Color;
import java.util.regex.Pattern;

public class HighlightFirstPattern {

    public static void main(String[] args) {

        // 加载 Word 文档
        Document document = new Document();
        try {
            document.loadFromFile("input.docx");

            // 定义正则表达式
            Pattern pattern = Pattern.compile(
                    "风险\s*(评估|分析|排查)");

            // 查找第一个符合正则表达式的文本
            TextSelection selection =
                    document.findPattern(pattern);

            // 设置匹配文本的高亮颜色
            if (selection != null) {
                selection.getAsOneRange()
                        .getCharacterFormat()
                        .setHighlightColor(Color.YELLOW);
            }

            // 保存 Word 文档
            document.saveToFile(
                    "HighlightFirstPattern.docx",
                    FileFormat.Docx_2013);

        } finally {
            document.dispose();
        }
    }
}

对于示例文档,首先匹配到的是"风险评估"。

2. 高亮所有正则匹配结果

若要处理所有符合条件的文本,则使用 ​​findAllPattern()​​:

typescript 复制代码
import com.spire.doc.Document;
import com.spire.doc.FileFormat;
import com.spire.doc.documents.TextSelection;

import java.awt.Color;
import java.util.regex.Pattern;

public class HighlightAllPatterns {

    public static void main(String[] args) {

        // 加载 Word 文档
        Document document = new Document();
        try {
            document.loadFromFile("input.docx");

            // 定义正则表达式
            Pattern pattern = Pattern.compile(
                    "风险\s*(评估|分析|排查)");

            // 查找所有符合正则表达式的文本
            TextSelection[] selections =
                    document.findAllPattern(pattern);

            // 遍历匹配结果并设置高亮
            if (selections != null) {
                for (TextSelection selection : selections) {
                    selection.getAsOneRange()
                            .getCharacterFormat()
                            .setHighlightColor(Color.YELLOW);
                }
            }

            // 保存 Word 文档
            document.saveToFile(
                    "HighlightAllPatterns.docx",
                    FileFormat.Docx_2013);

        } finally {
            document.dispose();
        }
    }
}

该方法接收 ​​java.util.regex.Pattern​​ 对象,并返回匹配结果数组。

对于准备的示例内容,预计会匹配到两处"风险评估"、一处"风险排查"和一处"风险分析",共 4 处。

值得注意的是,正则表达式实现的是基于规则的灵活匹配,并不等同于语义模糊搜索。例如,该表达式不会自动识别"潜在隐患"和"风险"之间的语义关联。

五、实际使用中需要注意的问题

1. 正则表达式不一定能跨越复杂的 Word 结构

Word 文档中的内容可能被拆分成多个文本对象,尤其是包含不同字体、域、文本框或修订内容时。

因此,对于普通段落中的文本,可以按照上述方式查找;但如果正则表达式需要跨段落或跨复杂文档对象匹配,应另外进行测试,不能简单假设所有连续可见的文字都能作为一个整体匹配。

2. 多个关键词可以用正则表达式合并查找

例如,要同时标记"风险""延期"和"违约",可以使用:

ini 复制代码
Pattern pattern = Pattern.compile(
        "风险|延期|违约");

再通过 ​​findAllPattern()​​ 获取所有匹配项。

这通常比针对每个关键词单独编写一段查找代码更简洁。

3. 高亮颜色可以修改

除了黄色,也可以使用其他颜色,例如:

scss 复制代码
selection.getAsOneRange()
        .getCharacterFormat()
        .setHighlightColor(Color.GREEN);

需要说明的是,​​setHighlightColor()​​ 设置的是 Word 文本高亮颜色,并不是字体颜色。

4. 输出文件应与源文件分开

示例中每次都重新加载 ​​input.docx​​,并保存为新的文件。这样既可以保留原始内容,也可以避免前一次高亮操作影响后续示例。

相关推荐
zyseo81 小时前
谷歌SEO 站内搜索优化实战:把站内搜索词变成关键词金矿
java·服务器·数据库
bug菌1 小时前
🤔同事突然问我:Spring的注解 @Component 和 @Service 有何不同?
java·spring boot·后端
佳児素花痴╮2 小时前
线程知识点
java·开发语言·jvm
fundoit2 小时前
为什么需要 Access Token 和 ID Token 两个令牌
java·spring·架构·github·oauth2
鱼宵3 小时前
Spring AI 流式输出:Flux + SSE 打字机,回答不再干等三秒
java·人工智能·spring·sse·springai·流式输出
shaibdoio3 小时前
AI主动获客的意图识别工程实现:从规则匹配到模型微调
java·开发语言·人工智能·长沙瞬维ai
for_ever_love__3 小时前
MySQL 事务隔离级别讲透:MVCC、幻读与四个级别怎么选
java·数据库·mysql·事务·mvcc·不可重复读·幻读
CoderYanger4 小时前
一轮复习——F.动态规划模型总结(入门篇)
java·开发语言·数据结构·算法·leetcode·职场和发展·动态规划
她的男孩4 小时前
打印模板草稿能保存,一点发布就报主从关系:我们把校验拆成了两档
java·spring boot·后端