Apache-Commons-Text
Apache-Commons-Text 及其他文本处理库
commons-text
StringsComparator 字符串对比(Myers差分算法)
@Test
public void myersStringDiff() {
String source = "The quick brxwn fox jmps over thee lazy dog";
String target = "The quick brown fox jumps over the lazy dog";
StringsComparator comparator = new StringsComparator(source, target);
StringBuilder result = new StringBuilder();
// 使用 CommandVisitor 来处理比较的结果
comparator.getScript().visit(new CommandVisitor<>() {
@Override
public void visitInsertCommand(Character c) {
result.append("[+").append(c).append("]");
}
@Override
public void visitKeepCommand(Character c) {
result.append(c);
}
@Override
public void visitDeleteCommand(Character c) {
result.append("[-").append(c).append("]");
}
});
System.out.println("source: " + source);
System.out.println("target: " + target);
System.out.println("diffs: " + result);
}
结果:
source: The quick brxwn fox jmps over thee lazy dog
target: The quick brown fox jumps over the lazy dog
diffs: The quick br[+o][-x]wn fox j[+u]mps over the[-e] lazy dog
LevenshteinDistance 编辑距离
编辑距离,又叫 Levenshtein 距离,莱文斯坦距离,是指两个字串之间,由一个转成另一个所需的最少编辑操作次数。
int distance = LevenshteinDistance.getDefaultInstance().apply(str1, str2);
测试计算 1000 对 20-50 随机长度字符串的编辑距离耗时约 55 毫秒。
@Test
public void testEditDistance() {
int count = 1000;
long ts = System.currentTimeMillis();
for (int i = 0; i < count; i++) {
String str1 = RandomStringUtils.randomAlphanumeric(20, 50);
String str2 = RandomStringUtils.randomAlphanumeric(20, 50);
int distance = LevenshteinDistance.getDefaultInstance().apply(str1, str2);
log.info("edit distance of {} and {} is {}", str1, str2, distance);
}
log.info("cal {} edit distance took {} ms", count, System.currentTimeMillis() - ts);
}
结果 cal 1000 edit distance took 55 ms
google/diff-match-patch 字符串对比(Myers差分算法)
google/diff-match-patch
https://github.com/google/diff-match-patch
Diff Match Patch 是一个高性能的文本处理库,旨在提供强大的算法来对两个字符串做差异(Diff)、匹配(Match)和补丁(Patch)。该项目最初由 Google 开发,并在多个编程语言中实现了相同的 API。
在线演示及diff计算
https://neil.fraser.name/software/diff_match_patch/demos/diff.html
diff-match-patch 基于 Myers 差分算法,Myers 算法由 Eugene W.Myers 在 1986 年发表的论文 《An O(ND) Difference Algorithm and Its Variations》中提出。Git 的 diff 算法就是 Myers 差分算法
An O(ND) Difference Algorithm and Its Variations
https://neil.fraser.name/writing/diff/myers.pdf
maven 引入依赖
<dependency>
<groupId>org.bitbucket.cowwoc</groupId>
<artifactId>diff-match-patch</artifactId>
<version>1.2</version>
</dependency>
DiffMatchPatch dmp = new DiffMatchPatch();
LinkedList<DiffMatchPatch.Diff> diffs = dmp.diffMain(source, target);
dmp.diffCleanupMerge(diffs);
dmp.diffCleanupMerge(diffs) 对差异列表进行合并和清理,其核心功能是:
- 合并相邻的相同类型操作,将连续的 INSERT/DELETE/EQUAL 操作合并为一个操作(例如多个连续的删除合并为一个大的删除区间)
- 消除无意义的空操作,删除零长度的差异片段,确保每个差异都有实际意义
- 优化差异语义,使最终输出的差异更符合人类理解的文本变化逻辑(如避免碎片化的字符级差异)
icu4j
unicode-org / icu
https://github.com/unicode-org/icu
ICU4J(International Components for Unicode for Java)是一个开源的 Java 类库,专注于提供全面的 Unicode 和全球化(i18n)支持,帮助开发者处理多语言、多区域环境下的文本、日期、数字等数据。
- Unicode 文本处理
- 字符集转换:支持 100+ 字符集与 Unicode 的相互转换(如 UTF-8、GBK、Shift-JIS),基于 IBM 多年积累的字符集数据,覆盖最全面。
- 规范化(Normalization):提供 NFC、NFD、NFKC、NFKD 四种 Unicode 规范化形式,确保文本符合 XML 和网络传输标准。
- 大小写转换:支持语言敏感的大小写转换(如土耳其语 “i” 的特殊处理)。
- 排序与字符串比较(Collation)
- 基于 Unicode 排序算法(UCA),实现语言敏感的字符串排序(如中文按拼音/笔画排序、德语变音符号处理)。
- 性能优于标准 Java
Collator
,且支持泰语、高棉语等复杂脚本。
- 国际化格式处理
- 日期/时间格式化:支持 30+ 历法(伊斯兰历、希伯来历、农历等)和时区计算,提供相对时间格式化(如“2 天前”)。
- 数字/货币格式化:支持科学计数法、拼写格式(如“一百元整”)、紧凑格式(如“1.2 万”)。
- 高级文本处理
- 文本边界分析:精准识别词、句、行边界,适用于自动换行或分词(尤其支持泰语、中文等无空格语言)。
- 双向文本(Bidi):处理混合方向文本(如阿拉伯语+英语),确保正确显示。
- 正则表达式:完全支持 Unicode 属性的正则引擎,性能优于标准 Java 实现。
- 实用工具
- 字符集检测:自动识别未标记文本的编码(如文件编码猜测)。
- 文本压缩:针对 Unicode 文本的高效压缩算法,适用于小字段存储。
中文繁体转简体
@Test
public void testTradToSimp() {
String src = "显著";
// 有问题,转换后 『显著』变成了『显着』
String dst = Transliterator.getInstance("Traditional-Simplified").transliterate(src);
System.out.println(dst);
}
Opencc4j
https://github.com/houbb/opencc4j
Opencc4j 是专为 Java 平台设计的中文繁简体转换工具库,基于 OpenCC(Open Chinese Convert)项目思想开发。它支持词组级别的精准转换,严格区分“一简对多繁”和“一简对多异”场景,并兼容异体字动态替换。适用于需处理跨区域中文文本的应用(如大陆、台湾、香港地区用词差异)。
- 精准繁简转换
- 词组级转换:不仅处理单字,还考虑上下文词组(如“头发”转繁体为“頭髮”,而非“头髮”)。
- 地区适配:支持中国大陆、台湾地区用词差异(如“鼠标”转台湾用语“滑鼠”)。
- 异体字兼容:动态替换异体字(如“裏”与“裡”)。
- 分词与判断能力
- 自定义分词:用户可实现
Segment
接口,灵活定制分词策略。 - 繁简检测:
- 判断字符/字符串是否为简体(
isSimple()
)或繁体(isTraditional()
)。 - 检测字符串中是否包含繁/简体(
containsSimple()
,containsTraditional()
)。
- 判断字符/字符串是否为简体(
- 列表提取:返回字符串中的简体/繁体字词列表(
simpleList()
,traditionalList()
)。
- 自定义分词:用户可实现
- 灵活性与扩展性
- 词库分离:转换规则与代码解耦,支持自定义词库导入。
- 多平台兼容:Windows、Linux、macOS 全平台支持。
使用示例:
// 简体转繁体
String traditional = ZhConverterUtil.toTraditional("生命不息,奋斗不止");
// 输出:生命不息,奮鬥不止
// 繁体转简体
String simple = ZhConverterUtil.toSimple("生命不息,奮鬥不止");
// 输出:生命不息,奋斗不止
// 检测是否为繁体
boolean isTrad = ZhConverterUtil.isTraditional("編"); // true
中文繁体转简体
@Test
public void testTradToSimp() {
String traditionalText = "显著";
String simplifiedText = ZhConverterUtil.toSimple(traditionalText);
System.out.println("原始文本: " + traditionalText);
System.out.println("转换结果: " + simplifiedText);
}
下一篇 Apache-PDFBox
页面信息
location:
protocol
: host
: hostname
: origin
: pathname
: href
: document:
referrer
: navigator:
platform
: userAgent
: