最近在处理一批 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,并保存为新的文件。这样既可以保留原始内容,也可以避免前一次高亮操作影响后续示例。