- Notifications
You must be signed in to change notification settings - Fork80
🇨🇳Open Chinese Convert is an opensource project for conversion between Traditional Chinese and Simplified Chinese.(java 中文繁简体转换,支持台湾、香港、中文日文转换。)
License
houbb/opencc4j
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Opencc4j 支持中文繁简体转换,考虑到词组级别。
严格区分「一简对多繁」和「一简对多异」。
完全兼容异体字,可以实现动态替换。
严格审校一简对多繁词条,原则为「能分则不合」。
词库和函数库完全分离,可以自由修改、导入、扩展。
兼容 Windows、Linux、Mac 平台。
支持自定义分词、引导类,优雅实现
支持判断单个字(词)是否为简体/繁体
支持返回字符串中简体/繁体的列表信息
支持中国台湾地区和大陆简体繁简体转换
支持中国香港地区和大陆简体繁简体转换
支持日文新字和大陆简体繁简体转换
兼容双字符汉字,【𨦟】【𪡃】等
- OpenCC
OpenCC 的思想非常优秀,做的也特别棒。但是没有特别为 java 提供的工具。
<dependency> <groupId>com.github.houbb</groupId> <artifactId>opencc4j</artifactId> <version>1.14.0</version></dependency>
核心工具列表如下:
| 序号 | 工具类 | 简介 |
|---|---|---|
| 1 | ZhConverterUtil | 基础的繁简体转换 |
| 2 | ZhTwConverterUtil | 中国台湾地区与大陆的繁简体转换 |
| 3 | ZhHkConverterUtil | 中国香港地区与大陆的繁简体转换 |
| 4 | ZhJpConverterUtil | 日文新字与大陆的繁简体转换 |
所有的工具类方法具有相同的方法设计,便于记忆。
核心方法如下:
| 序号 | api 方法 | 简介 |
|---|---|---|
| 1 | toSimple(String) | 转为简体 |
| 2 | toTraditional(String) | 转为繁体 |
| 3 | simpleList(String) | 返回包含的简体列表 |
| 4 | traditionalList(String) | 返回包含的繁体列表 |
| 5 | toSimple(char) | 返回单个汉字对应的所有简体字列表 |
| 6 | toTraditional(char) | 返回单个汉字对应的所有繁体字列表 |
| 7 | isSimple(String) | 是否全部为简体 |
| 8 | isSimple(char) | 单个字符是否为简体 |
| 9 | containsSimple(String) | 字符中是否为包含简体 |
| 10 | isTraditional(String) | 是否全部为繁体 |
| 11 | isTraditional(char) | 单个字符是否为繁体 |
| 12 | containsTraditional(String) | 字符中是否为包含繁体 |
| 13 | isChinese(String) | 是否全部为中文 |
| 14 | isChinese(char) | 单个字符是否为中文 |
| 15 | containsChinese(char) | 字符串中是否包含中文 |
Stringoriginal ="生命不息,奮鬥不止";Stringresult =ZhConverterUtil.toSimple(original);Assert.assertEquals("生命不息,奋斗不止",result);
Stringoriginal ="生命不息,奋斗不止";Stringresult =ZhConverterUtil.toTraditional(original);Assert.assertEquals("生命不息,奮鬥不止",result);
对单个字符或者词组进行繁简体判断。
Assert.assertTrue(ZhConverterUtil.isSimple('奋'));Assert.assertTrue(ZhConverterUtil.isSimple("奋"));Assert.assertTrue(ZhConverterUtil.isSimple("奋斗"));Assert.assertFalse(ZhConverterUtil.isSimple('奮'));Assert.assertFalse(ZhConverterUtil.isSimple("奮"));Assert.assertFalse(ZhConverterUtil.isSimple("奮鬥"));Assert.assertFalse(ZhConverterUtil.isSimple("奮斗"));Assert.assertFalse(ZhConverterUtil.isSimple("beef"));
Assert.assertTrue(ZhConverterUtil.containsSimple("奋"));Assert.assertTrue(ZhConverterUtil.containsSimple("奋斗"));Assert.assertTrue(ZhConverterUtil.containsSimple("奋斗2023"));Assert.assertFalse(ZhConverterUtil.containsSimple("編"));Assert.assertFalse(ZhConverterUtil.containsSimple("編號"));
Assert.assertTrue(ZhConverterUtil.isTraditional('編'));Assert.assertTrue(ZhConverterUtil.isTraditional("編"));Assert.assertTrue(ZhConverterUtil.isTraditional("編號"));Assert.assertFalse(ZhConverterUtil.isTraditional('编'));Assert.assertFalse(ZhConverterUtil.isTraditional("编"));Assert.assertFalse(ZhConverterUtil.isTraditional("编号"));Assert.assertFalse(ZhConverterUtil.isTraditional("编號"));
Assert.assertTrue(ZhConverterUtil.containsTraditional("編"));Assert.assertTrue(ZhConverterUtil.containsTraditional("編號"));Assert.assertTrue(ZhConverterUtil.containsTraditional("編號2023"));Assert.assertFalse(ZhConverterUtil.containsTraditional("号"));Assert.assertFalse(ZhConverterUtil.containsTraditional("编号"));
返回字符串中繁简体对应的词、字列表,默认支持中文分词。
繁简体列表返回的词组和分词策略紧密相关。
finalStringoriginal ="生命不息奋斗不止";finalList<String>resultList =ZhConverterUtil.simpleList(original);Assert.assertEquals("[生, 命, 不, 息, 奋斗, 不, 止]",resultList.toString());
PS: 很多字是同体字。
finalStringoriginal ="生命不息奮鬥不止";finalList<String>resultList =ZhConverterUtil.traditionalList(original);Assert.assertEquals("[生, 命, 不, 息, 奮, 鬥, 不, 止]",resultList.toString());
Assert.assertEquals("[幹, 乾, 干]",ZhConverterUtil.toTraditional('干').toString());Assert.assertEquals("[發, 髮]",ZhConverterUtil.toTraditional('发').toString());
Assert.assertEquals("[测]",ZhConverterUtil.toSimple('測').toString());
Assert.assertTrue(ZhConverterUtil.isChinese("你"));Assert.assertTrue(ZhConverterUtil.isChinese("你好"));Assert.assertTrue(ZhConverterUtil.isChinese('你'));Assert.assertFalse(ZhConverterUtil.isChinese("你0"));Assert.assertFalse(ZhConverterUtil.isChinese("10"));Assert.assertFalse(ZhConverterUtil.isChinese('0'));Assert.assertFalse(ZhConverterUtil.isChinese(""));Assert.assertFalse(ZhConverterUtil.isChinese(null));
Assert.assertTrue(ZhConverterUtil.containsChinese("你"));Assert.assertTrue(ZhConverterUtil.containsChinese("你好"));Assert.assertTrue(ZhConverterUtil.containsChinese("你0"));Assert.assertFalse(ZhConverterUtil.containsChinese("10"));Assert.assertFalse(ZhConverterUtil.containsChinese(""));Assert.assertFalse(ZhConverterUtil.containsChinese(null));
为保证方法的一致性,引入ZhTwConverterUtil 工具类,支持方法和ZhConverterUtil 保持一致。
简体到繁体:
Stringoriginal ="使用互联网";Stringresult =ZhTwConverterUtil.toTraditional(original);Assert.assertEquals("使用網際網路",result);
繁体到简体:
Stringoriginal ="使用網際網路";Stringresult =ZhTwConverterUtil.toSimple(original);Assert.assertEquals("使用互联网",result);
v1.12.0 版本支持。
为保证方法的一致性,引入ZhHkConverterUtil 工具类,支持方法和ZhConverterUtil 保持一致。
/** * 大陆简体==>香港正體 * @since 1.12.0 */@TestpublicvoidtestHkTraditional() {Stringoriginal ="千家万户瞳瞳日 总把新桃换旧符";Stringresult =ZhHkConverterUtil.toTraditional(original);Assert.assertEquals("千家萬户瞳瞳日 總把新桃換舊符",result);}/** * 香港正體==>大陆简体 */@TestpublicvoidtestHkSimple() {Stringoriginal ="千家萬户瞳瞳日 總把新桃換舊符";Stringresult =ZhHkConverterUtil.toSimple(original);Assert.assertEquals("千家万户瞳瞳日 总把新桃换旧符",result);}
v1.13.0 版本支持。
为保证方法的一致性,引入ZhJpConverterUtil 工具类,支持方法和ZhConverterUtil 保持一致。
实际流程:简体==》标准繁体==》日文新字
/** * 大陆简体==>标准繁体=》日文 */@TestpublicvoidtestJpTraditional() {Stringoriginal ="我在日本学习音乐,并学习了龙的字。";Stringresult =ZhJpConverterUtil.toTraditional(original);Assert.assertEquals("我在日本学習音楽,並学習了竜的字。",result);}/** * 日文=>标准繁体=>简体 */@TestpublicvoidtestJpSimple() {Stringoriginal ="我在日本学習音楽,並学習了竜的字。";Stringresult =ZhJpConverterUtil.toSimple(original);Assert.assertEquals("我在日本学习音乐,并学习了龙的字。",result);}
主要的可配置项包含了分词和数据集合。
二者都是可以配置,并且支持自定义的。
默认工具类等价于如下:
ZhConvertBootstrap.newInstance() .segment(Segments.defaults()) .dataMap(DataMaps.defaults()).init();
中国台湾地区配置等价于:
ZhConvertBootstrap.newInstance() .segment(Segments.twFastForward()) .dataMap(DataMaps.taiwan()).init();
你可以通过Segments 工具类获取系统内置的分词实现。
| 序号 | 方法 | 准确性 | 性能 | 备注 |
|---|---|---|---|---|
| 1 | defaults() | 高 | 高 | 默认分词形式,暂时为fastForward 策略 |
| 2 | fastForward() | 较高 | 高 | fast-forward 分词策略 |
| 3 | chars() | 低 | 高 | 将字符串转换为单个字符列表,一般不建议使用 |
| 4 | huaBan() | 高 | 一般 | 花瓣的结巴分词策略 |
花瓣结巴分词在使用时,需要自行引入结巴分词依赖。
<dependency> <groupId>com.huaban</groupId> <artifactId>jieba-analysis</artifactId> <version>1.0.2</version></dependency>
你有时候可能除了上述的两种分词方式,会有更加适合自己业务的分词实现。
Opencc4j 支持自定义分词实现,只需要实现分词接口Segment
- 接口内容
publicinterfaceSegment {/** * 分词 * @param original 原始信息 * @return 分词后的列表 */List<String>seg(finalStringoriginal);}
/** * 一个最简单的分词实现。 * 注意:仅仅做演示,不可实际使用。 */publicclassFooSegmentimplementsSegment {@OverridepublicList<String>seg(Stringoriginal) {returnArrays.asList(original,"测试"); }}
我们自定义的分词,直接在默认添加“测试”这样的信息。
finalStringoriginal ="寥落古行宫,宫花寂寞红。白头宫女在,闲坐说玄宗。";finalSegmentsegment =newFooSegment();finalStringresult =ZhConvertBootstrap.newInstance() .segment(segment) .init() .toTraditional(original);Assert.assertEquals("寥落古行宮,宮花寂寞紅。白頭宮女在,閒坐說玄宗。測試",result);
不同的地区,对应的转换规则是不同的。
具体参考一下台湾地区的使用方式即可。
IDataMap 的接口如下。
/** * 数据 map 接口 * @author binbin.hou * @since 1.5.2 */publicinterfaceIDataMap {/** * 繁体=》简体 词组 * @return 结果 * @since 1.5.2 */Map<String,List<String>>tsPhrase();/** * 繁体=》简体 单个字 * @return 结果 * @since 1.5.2 */Map<String,List<String>>tsChar();/** * 简体=》繁体 词组 * @return 结果 * @since 1.5.2 */Map<String,List<String>>stPhrase();/** * 简体=》繁体 单个字 * @return 结果 * @since 1.5.2 */Map<String,List<String>>stChar();/** * 繁体字所有字符 * @return 繁体字所有字符 * @since 1.6.2 */Set<String>tChars();/** * 简体字所有字符 * @return 繁体字所有字符 * @since 1.8.0 */Set<String>sChars();}
如果需要拓展对应的数据,建议继承原始的实现,然后添加额外的数据信息即可。
可以参考中国台湾地区实现
ps: 后续考虑引入更加简单的实现方式,比如基于文本拓展,不过可扩展性没有接口灵活。
用于用户参考,可以自定义实现自己的实现,更加符合实际业务。
v1.9.0 开始支持,方便用户拓展。
比如首先自定义一个 dataMap 类,集成 AbstractDataMapExtra 可以在指定的 IDataMap 基础上额外指定词组等信息。
publicclassMyFooDataMapExtraextendsAbstractDataMapExtra {publicMyFooDataMapExtra(IDataMapbaseDataMap) {super(baseDataMap); }// 默认在基本的繁简体基础上拓展publicMyFooDataMapExtra() {this(DataMaps.defaults()); }privateMap<String,List<String>>of(Stringkey,List<String>list) {Map<String,List<String>>map =newHashMap<>();map.put(key,list);returnmap; }@OverrideprotectedMap<String,List<String>>tsPhraseExtra() {// 估计写了个错的,用来演示returnof("風玥",Arrays.asList("风月")); }@OverrideprotectedMap<String,List<String>>tsCharExtra() {returnnull; }@OverrideprotectedMap<String,List<String>>stPhraseExtra() {// 估计写了个错的returnof("风月",Arrays.asList("風玥")); }@OverrideprotectedMap<String,List<String>>stCharExtra() {returnnull; }}
我们只需要在引导类 ZhConvertBootstrap 指定我们的 dataMap 和对应的分词策略,即可。
// 1.1自定义的额外数据集finalIDataMapdataMap =newMyFooDataMapExtra();// 1.2 指定分词策略finalSegmentsegment =newDataMapFastForwardSegment(dataMap);// 2. 指定ZhConvertBootstrapbs =ZhConvertBootstrap.newInstance() .dataMap(dataMap) .segment(segment) .init() ;// 3. 使用Assert.assertEquals(bs.toTraditional("人生自是有情痴,此恨不关风月"),"人生自是有情癡,此恨不關風玥");Assert.assertEquals(bs.toSimple("人生自是有情癡,此恨不關風玥"),"人生自是有情痴,此恨不关风月");
V1.11.0 版本支持。
有时候我们需要判断一个字符串是否为繁简体,isSimple()、isTraditional() 默认要求全部匹配,无法满足全部场景。
这里允许用户自定义相关的策略。
内置策略见ZhMatches 工具方法。
| 策略 | 说明 | 备注 |
|---|---|---|
| simpleAll() | 满足全部简体 | isSimple 判断时,默认策略 |
| simpleAny() | 满足任一简体 | - |
| simpleOverHalf() | 满足超过一半简体 | - |
| traditionalAll() | 满足全部繁体 | isTraditional 判断时,默认策略 |
| traditionalAny() | 满足任一繁体 | - |
| traditionalOverHalf() | 满足超过一半繁体 | - |
// 全部ZhConvertBootstrapbs =ZhConvertBootstrap.newInstance() .isSimpleMatch(ZhMatches.simpleAll()) .init();Stringtext ="123我456";Assert.assertFalse(bs.isSimple(text));// 任一bs.isSimpleMatch(ZhMatches.simpleAny()).init();Assert.assertTrue(bs.isSimple(text));
// 全部ZhConvertBootstrapbs =ZhConvertBootstrap.newInstance() .isTraditionalMatch(ZhMatches.traditionalAll()) .init();Stringtext ="123俺們456";Assert.assertFalse(bs.isTraditional(text));// 任一bs.isTraditionalMatch(ZhMatches.traditionalAny()).init();Assert.assertTrue(bs.isTraditional(text));;
如果系统内置的策略不满足,你可以自定义。
实现 ZhMatch 接口,引导类中指定即可使用。
OpenCC 提供的原始数据信息。
jieba-analysis 提供中文分词
需求和 BUG 在这里,欢迎提供宝贵的建议。
如果对您有帮助,欢迎 Star 鼓励作者。
数据字典插件化
考虑长文本分段,并行转换
About
🇨🇳Open Chinese Convert is an opensource project for conversion between Traditional Chinese and Simplified Chinese.(java 中文繁简体转换,支持台湾、香港、中文日文转换。)
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Releases
Packages0
Contributors4
Uh oh!
There was an error while loading.Please reload this page.