Giter VIP home page Giter VIP logo

houbb / opencc4j Goto Github PK

View Code? Open in Web Editor NEW
456.0 13.0 69.0 847 KB

🇨🇳Open Chinese Convert is an opensource project for conversion between Traditional Chinese and Simplified Chinese.(java 中文繁简体转换)

Home Page: https://houbb.github.io/opensource/opencc4j

License: Apache License 2.0

Batchfile 1.37% Shell 3.14% Java 95.48%
java java7 chinese opencc nlp trie trie-tree dfa simple-tranditional

opencc4j's Introduction

Opencc4j

Opencc4j 支持中文繁简体转换,考虑到词组级别。

Build Status Maven Central Coverage Status Open Source Love

在线体验

Features 特点

  • 严格区分「一简对多繁」和「一简对多异」。

  • 完全兼容异体字,可以实现动态替换。

  • 严格审校一简对多繁词条,原则为「能分则不合」。

  • 词库和函数库完全分离,可以自由修改、导入、扩展。

  • 兼容 Windows、Linux、Mac 平台。

  • 支持自定义分词

  • 支持判断单个字(词)是否为简体/繁体

  • 支持返回字符串中简体/繁体的列表信息

  • 支持****地区繁简体转换

v1.8.1 版本变更

  • 修正 的转换问题

变更日志

创作缘由

  • OpenCC

OpenCC 的**非常优秀,做的也特别棒。但是没有特别为 java 提供的工具。

  • jopencc

jopencc 没有提供分词功能。



快速开始

maven 引入

<dependency>
    <groupId>com.github.houbb</groupId>
    <artifactId>opencc4j</artifactId>
    <version>1.8.1</version>
</dependency>

api 概览

核心工具列表如下:

序号 工具类 简介
1 ZhConverterUtil 基础的繁简体转换
2 ZhTwConverterUtil **地区的繁简体转换

所有的工具类方法具有相同的方法设计,便于记忆。

核心方法如下:

序号 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) 字符串中是否包含中文

繁简体转换

转为简体 toSimple

String original = "生命不息,奮鬥不止";
String result = ZhConverterUtil.toSimple(original);
Assert.assertEquals("生命不息,奋斗不止", result);

转为繁体 toTraditional

String original = "生命不息,奋斗不止";
String result = ZhConverterUtil.toTraditional(original);
Assert.assertEquals("生命不息,奮鬥不止", result);

繁简体判断

对单个字符或者词组进行繁简体判断。

是否为简体 isSimple

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"));

是否包含简体 containsSimple

Assert.assertTrue(ZhConverterUtil.containsSimple("奋"));
Assert.assertTrue(ZhConverterUtil.containsSimple("奋斗"));
Assert.assertTrue(ZhConverterUtil.containsSimple("奋斗2023"));

Assert.assertFalse(ZhConverterUtil.containsSimple("編"));
Assert.assertFalse(ZhConverterUtil.containsSimple("編號"));

是否为繁体 isTraditional

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("编號"));

是否包含繁体 containsTraditional

Assert.assertTrue(ZhConverterUtil.containsTraditional("編"));
Assert.assertTrue(ZhConverterUtil.containsTraditional("編號"));
Assert.assertTrue(ZhConverterUtil.containsTraditional("編號2023"));

Assert.assertFalse(ZhConverterUtil.containsTraditional("号"));
Assert.assertFalse(ZhConverterUtil.containsTraditional("编号"));

句子中包含的繁简体列表返回

返回字符串中繁简体对应的词、字列表,默认支持中文分词。

繁简体列表返回的词组和分词策略紧密相关。

简体列表 simpleList

final String original = "生命不息奋斗不止";
final List<String> resultList = ZhConverterUtil.simpleList(original);

Assert.assertEquals("[生, 命, 不, 息, 奋斗, 不, 止]", resultList.toString());

繁体列表 traditionalList

PS: 很多字是同体字。

final String original = "生命不息奮鬥不止";
final List<String> resultList = ZhConverterUtil.traditionalList(original);

Assert.assertEquals("[生, 命, 不, 息, 奮, 鬥, 不, 止]", resultList.toString());

单个汉字对应的繁简体列表

繁体字列表

Assert.assertEquals("[幹, 乾, 干]", ZhConverterUtil.toTraditional('干').toString());
Assert.assertEquals("[發, 髮]", ZhConverterUtil.toTraditional('发').toString());

简体字列表

Assert.assertEquals("[测]", ZhConverterUtil.toSimple('測').toString());

中文工具方法

是否为中文 isChinese

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));

是否包含中文 containsChinese

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 保持一致。

测试用例

简体到繁体:

String original = "使用互联网";
String result = ZhTwConverterUtil.toTraditional(original);
Assert.assertEquals("使用網際網路", result);

繁体到简体:

String original = "使用網際網路";
String result = ZhTwConverterUtil.toSimple(original);
Assert.assertEquals("使用互联网", result);

配置引导类

引导类说明

主要的可配置项包含了分词和数据集合。

二者都是可以配置,并且支持自定的。

默认配置

默认工具类等价于如下:

ZhConvertBootstrap.newInstance()
                .segment(Segments.defaults())
                .dataMap(DataMaps.defaults());

****地区配置

****地区配置等价于:

ZhConvertBootstrap.newInstance()
                .segment(Segments.defaults())
                .dataMap(DataMaps.taiwan());

中文分词策略

系统内置分词方式

你可以通过 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

  • 接口内容
public interface Segment {

    /**
     * 分词
     * @param original 原始信息
     * @return 分词后的列表
     */
    List<String> seg(final String original);

}

测试代码

自定义分词实现类

/**
 * 一个最简单的分词实现。
 * 注意:仅仅做演示,不可实际使用。
 */
public class FooSegment implements Segment {
    @Override
    public List<String> seg(String original) {
        return Arrays.asList(original, "测试");
    }
}

分词测试

我们自定义的分词,直接在默认添加“测试”这样的信息。

final String original = "寥落古行宫,宫花寂寞红。白头宫女在,闲坐说玄宗。";
final Segment segment = new FooSegment();

final String result = ZhConvertBootstrap.newInstance()
        .segment(segment)
        .toTraditional(original);

Assert.assertEquals("寥落古行宮,宮花寂寞紅。白頭宮女在,閒坐說玄宗。測試", result);

数据接口自定义

不同的地区,对应的转换规则是不同的。

具体参考一下**地区的使用方式即可。

接口说明

IDataMap 的接口如下。

/**
 * 数据 map 接口
 * @author binbin.hou
 * @since 1.5.2
 */
public interface IDataMap {

    /**
     * 繁体=》简体 词组
     * @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: 后续考虑引入更加简单的实现方式,比如基于文本拓展,不过可扩展性没有接口灵活。

技术鸣谢

OpenCC

OpenCC 提供的原始数据信息。

花瓣

jieba-analysis 提供中文分词

Issues & Bugs

需求和 BUG 在这里,欢迎提供宝贵的建议。

如果对您有帮助,欢迎 Star 鼓励作者。

NLP 开源矩阵

pinyin 汉字转拼音

pinyin2hanzi 拼音转汉字

segment 高性能中文分词

opencc4j 中文繁简体转换

nlp-hanzi-similar 汉字相似度

word-checker 拼写检测

sensitive-word 敏感词

后期 Road-Map

  • 数据字典插件化

  • 考虑长文本分段,并行转换

opencc4j's People

Contributors

dependabot[bot] avatar houbb avatar jackychu0830 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

opencc4j's Issues

并发条件下存在BUG

并发条件下存在BUG

验证此BUG场景的存在

修复此BUG

修复方式:

  1. 仍然提供线程不安全的方式,但同时提供线程安全的方式
  2. 将现有的线程不安全的方式统一修改为线程安全的方式(牺牲性能)

关于繁体识别失误的原因和一个解决方案

//3. 如果不是繁体的词组,则直接进行单个 char 的分词,如果每一个字都是繁体,则认为是繁体。

这里判断有个问题,必须每一个字符都是字典里有的繁体,如果一句话里有一个没有简化的字(既不是简体也不是繁体,譬如:繁,之,好……),判断就会失效。

可以参照 iOS 的逻辑来修改
如果中文语句中有一个简体别匹配,整句话就识别成简体,这时转换就转换成繁体,
如果每一个字都不在简体字体里就转成繁体。

需要实现相似功能的可以把工具类拷贝出来改改

public boolean isSimple(String charOrPhrase) {
    if(StringUtil.isEmpty(charOrPhrase)) {
        return false;
    }

    final int length = charOrPhrase.length();

    if(length == 1) {
        return dataKeyContains(dataMap.stChar(), charOrPhrase);
    }

    boolean isSimplePhrase = dataKeyContains(dataMap.stPhrase(), charOrPhrase);
    if(isSimplePhrase) {
        return true;
    }

    List<String> segList = Instances.singleton(CharSegment.class).seg(charOrPhrase);
    for(String seg : segList) {
        if(isSimple(seg)) {
            return true;
        }
    }

    return false;
}

判断是否繁体时错误

zhConvertBootstrap.isTraditional("法國號 Fritz Kruspe")
当一段字符串中出现英文或者空格时会返回false
@OverRide
public boolean isTraditional(char c) {
if(!isChinese(c)) {
return false;
}

    // 繁体字符包含
    return this.dataMap.tChars().contains(c+"");
}

debug 发现是isChinese方法返回的false

繁体字:煇 在linux下转不成功

代码:
if(StringUtils.isNotBlank(order.getReceiverName())){
String getReceiverName = new String(order.getReceiverName().getBytes(), "utf-8");
LOG.info("getReceiverName=============================: "+getReceiverName);

		String convertToSimplereceiverName = ZhConverterUtil.convertToSimple(getReceiverName);
		LOG.info("convertToSimplereceiverName=============================: "+convertToSimplereceiverName);

		String receiverNameNew = org.springframework.util.StringUtils.trimAllWhitespace(convertToSimplereceiverName);

		LOG.info("receiverNameNew=============================: "+receiverNameNew);
		order.setReceiverName(receiverNameNew);
	}

现象:
================: 陈文煇
-|2020-01-08 16:00:34.593|INFO |TID: N/A|DubboServerHandler-10.0.253.42:31880-thread-230|c.s.o.services.impl.OrderManageV2.convertToOrder:4650-convertToSimplereceiverName=============================: 陈文긩
-|2020-01-08 16:00:34.594|INFO |TID: N/A|DubboServerHandler-10.0.253.42:31880-thread-230|c.s.o.services.impl.OrderManageV2.convertToOrder:4654-receiverNameNew=============================: 陈文긩

可否支持更改字詞設定?

目前代碼裡定只讀取 STPhrases.txt
照 OpenCC 的規格,是能把字詞轉換成台灣或香港在地的用語
不知可否支持讓使用者自行設定呢?

Crash

您好,我使用 1.5.2 的版本,發生了閃退的問題
以下閃退資訊

截圖 2020-06-26 下午1 23 09

isTraditional类似函数判断繁体时存在错误

字典文件加载时,按字符切分之后都加载进了 tSet,但是字典里面不是每个繁体词语,构成的字符都是繁体字,导致加载进了很多简体字符,使用时候会出现误判

public Set<String> tChars() {
        //DLC-保证只初始化一次
        if(CollectionUtil.isNotEmpty(tSet)) {
            return tSet;
        }

        if(CollectionUtil.isEmpty(tSet)) {
            synchronized (tSet) {
                // DLC
                if(CollectionUtil.isEmpty(tSet)) {
                    // 繁体=》简体 词组
                    Map<String, List<String>> tsPhrase = this.tsPhrase();
                    this.addCharToSet(tSet, tsPhrase.keySet());

                    //繁体=》简体 单个字
                    Map<String, List<String>> tsChar = this.tsChar();
                    this.addCharToSet(tSet, tsChar.keySet());

                    //简体=》繁体 词组
                    Map<String, List<String>> stPhrase = this.stPhrase();
                    for(Map.Entry<String, List<String>> entry : stPhrase.entrySet()) {
                        this.addCharToSet(tSet, entry.getValue());
                    }

                    //简体=》繁体 单个字
                    Map<String, List<String>> stChar = this.stChar();
                    for(Map.Entry<String, List<String>> entry : stChar.entrySet()) {
                        this.addCharToSet(tSet, entry.getValue());
                    }

                    // 文本字典
                    List<String> tcLines = StreamUtil.readAllLines("/data/dictionary/tc.txt");
                    for(String line : tcLines) {
                        tSet.addAll(StringUtil.toCharStringList(line));
                    }
                }
            }
        }

        return tSet;
    }

query=支付寶 isSample判断为真 与预期不符

谢谢之前回复~
又试了下,的确单个字没问题,但是如果是"支付寶",判断这个词是简体。
看到你的判断逻辑里,认为一个词所有字都是繁体才是繁体,但是"支付"这两个字是繁简同体,在我看来这个词"支付寶"判断为繁体是否最符合呢?
image

词:支付寶
isSample判断为真

袖里乾坤 转换错误

python转换正确,
默认segment,java转换为[袖里干坤]
切换为花瓣jieba分词,仍然是[袖里干坤]
版本1.6.0

部分生僻字转小写之后会得到一个乱码(不可见字符)

例如“嘪球”在转换之后得到“𪡃球”,还有其他一些字也存在这个问题。查阅源码发现是 TSCharacters.txt 文件中定义的 “嘪 𪡃”导致,是否可以将这类会产生乱码的字用转化之前的字本身来代替,作为兜底策略,防止得到乱码。只需要把该文件中,映射后为乱码的kv对替换掉即可,例如“嘪 𪡃”替换成“嘪 嘪”。

文言文转换为中文简体

看到这个简体和繁体转换非常开心。要是能把文言文转换成中文简体的能力加进去就好了。

输出字符串中所包含的简体字/繁体字?

这个功能可以拆解为两个子方法:
(1)字符串分词
(2)判断词组是否为繁体/简体
然后返回对应的词组即可。

【可能存在的问题】
当一个字繁简体同时存在时,是优先为繁体/简体,还是二者都包含?

转换成不可见字符,且转换前后字符长度不一致

问题
繁简转换失败,并且改变了字符长度

版本

        <dependency>
            <groupId>com.github.houbb</groupId>
            <artifactId>opencc4j</artifactId>
            <version>1.6.0</version>
        </dependency>

使用方式

	String originText = "齾";
	String simpleText = ZhConverterUtil.toSimple(originText, Segments.defaults());
	System.out.println(String.format("%s, length: %d", originText, originText.length()));
	System.out.println(String.format("%s, length: %d", simpleText, simpleText.length()));

输出

齾, length: 1
𫜰, length: 2

toTraditional(char) 返回 所有繁体字列表 問題

你好
我發現simpleList(String), simpleList(String) 如果以繁體主的會出現問題
例如 "生命不息奋斗不止";
simpleList調用後 對繁體使用者來說,結果應該為 “奋,斗”
traditionalList調用後 對繁體使用者來說,結果應該為 “生, 命, 不, 息, 不, 止”
我想問下可否設定一個值對應繁簡地區生成不同的結果, 或者新增一個功能可以抽出繁簡相異的字詞

关于异体字的转换规则

您的项目很棒。我的需求主要是繁体异体转换为简体。
使用陈书序 一段文字测试:
陳書六本紀三十列傳凡三十六篇唐散騎常侍姚思廉撰始思廉父察梁陳之史官也錄二代之事未就而陳亡隋文帝見察甚重之每就察訪梁陳故事察因以所論載每一篇成輙奏之而文帝亦遣虞世基就察求其書又未就而察死察之將死屬思㢘以繼其業唐興武徳五年高祖以自魏以來二百餘嵗世統數更史事放逸乃詔撰次而思廉遂受詔為陳書久之猶不就貞觀三年遂詔論撰於秘書内省十年正月壬子始上之觀察等之為此書厯三世傳父子更數十嵗而後乃成盖其難如此然及其既成與宋魏梁齊等書世亦傳之者少故學者於其行事之迹亦罕得而詳也而其書亦以罕傳則自秘府所藏往往脱悞嘉祐六年八月始詔校讐使可鏤板行之天下而臣等言梁陳等書缺獨館閣所藏恐不足以定著願詔京師及州縣藏書之家使悉上之先皇帝為下其事至七年冬稍稍始集臣等以相校至八年七月陳書三十六篇者始校定可傳之學者其疑者亦不敢損益特各疏於篇末其書舊無目列傳名氏多闕謬因别為目錄一篇使覽者得詳焉夫陳之為陳盖偷為一切之計非有先王經紀禮義風化之美制治之法可章示後世然而兼權尚訃明於任使恭儉愛人則其始之所以興惑於邪臣溺於嬖妾忘患縱欲則其終之所以亡興亡之端莫非自己致者至於有所因造以為號令威刑職官州郡之制雖其事已淺然亦各施於一時皆學者之所不可不考也而當時之士自爭奪詐偽茍得偷合之徒尚不得不列以為世戒而況於壊亂之中蒼皇之際士之安貧樂義取舍去就不為患禍勢利動其心者亦不絶於其間若此人者可謂篤於善矣盖古人之所思見而不可得風雨之詩所為作者也安可使之泯泯不少概見於天下哉則陳之史其可廢乎盖此書成之既難其後又久不顯及宋興已百年古文遺事靡不畢講而始得盛行於天下列於學官其傳之之難又如此豈非遭遇固自有時也哉臣恂臣穆臣藻臣覺臣彦若臣洙臣鞏謹叙目錄昧死上

获得简体转换结果如下:
陈书六本纪三十列传凡三十六篇唐散骑常侍姚思廉撰始思廉父察梁陈之史官也录二代之事未就而陈亡隋文帝见察甚重之每就察访梁陈故事察因以所论载每一篇成輙奏之而文帝亦遣虞世基就察求其书又未就而察死察之将死属思㢘以继其业唐兴武徳五年高祖以自魏以来二百余岁世统数更史事放逸乃诏撰次而思廉遂受诏为陈书久之犹不就贞观三年遂诏论撰于秘书内省十年正月壬子始上之观察等之为此书厯三世传父子更数十岁而后乃成盖其难如此然及其既成与宋魏梁齐等书世亦传之者少故学者于其行事之迹亦罕得而详也而其书亦以罕传则自秘府所藏往往脱悮嘉祐六年八月始诏校讐使可镂板行之天下而臣等言梁陈等书缺独馆阁所藏恐不足以定著愿诏京师及州县藏书之家使悉上之先皇帝为下其事至七年冬稍稍始集臣等以相校至八年七月陈书三十六篇者始校定可传之学者其疑者亦不敢损益特各疏于篇末其书旧无目列传名氏多阙谬因别为目录一篇使览者得详焉夫陈之为陈盖偷为一切之计非有先王经纪礼义风化之美制治之法可章示后世然而兼权尚讣明于任使恭俭爱人则其始之所以兴惑于邪臣溺于嬖妾忘患纵欲则其终之所以亡兴亡之端莫非自己致者至于有所因造以为号令威刑职官州郡之制虽其事已浅然亦各施于一时皆学者之所不可不考也而当时之士自争夺诈伪茍得偷合之徒尚不得不列以为世戒而况于壊乱之中苍皇之际士之安贫乐义取舍去就不为患祸势利动其心者亦不绝于其间若此人者可谓笃于善矣盖古人之所思见而不可得风雨之诗所为作者也安可使之泯泯不少概见于天下哉则陈之史其可废乎盖此书成之既难其后又久不显及宋兴已百年古文遗事靡不毕讲而始得盛行于天下列于学官其传之之难又如此岂非遭遇固自有时也哉臣恂臣穆臣藻臣觉臣彦若臣洙臣巩谨叙目录昧死上

经校读发现:徳厯悮茍讐壊 数字异体字未有做转换逻辑。
其中:
徳:武徳五年,期望为德
厯:此書厯三世,期望为历
悮:往往脱悮,期望为误
茍:茍得偷合之徒,期望为苟
讐:始诏校讐,期望为雠
壊:而况于壊乱之中,期望为坏

按您的项目文档,异体字也当转换为简体。请问是特殊规则还是异体字不视做繁体?如果我要实现以上数字类似的异体字的转换,只能通过实现接口,增加映射关系吗?

maven 直接引用在匿名内部类中报class 不存在

`
public static void save2db(JSONArray tangs){
DataSource dataSource = new SingleConnectionDataSource("XXXX","name","password",true);
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.batchUpdate("insert into Table(column1,column2,column3,column4,column5)VALUES(?,?,?,?,?)", new BatchPreparedStatementSetter() {

        @Override
        public void setValues(PreparedStatement preparedStatement, int i) throws SQLException {
            JSONObject tang = tangs.getJSONObject(i);
            preparedStatement.setString(1,tang.getString("aa"));
            preparedStatement.setString(2,tang.getString("bb"));
            //preparedStatement.setString(3,tang.getString("cc"));
            JSONArray paragraphs = tang.getJSONArray("dd");
            if(paragraphs != null && paragraphs.size() > 0){
                String content = "";
                for (int j = 0; j < paragraphs.size(); j++) {
                    content+=("<p>"+paragraphs.getString(j)+"<p>");
                }
                preparedStatement.setString(3,content);
                preparedStatement.setString(4, ZhConverterUtil.toSimple(content));
            }else {
                preparedStatement.setString(3,"");
                preparedStatement.setString(4,"");
            }

            preparedStatement.setString(5,"aa");


        }

        @Override
        public int getBatchSize() {
            return tangs.size();
        }
    });
}

}
`

异常信息:
Exception in thread "main" java.lang.NoClassDefFoundError: com/github/houbb/heaven/support/instance/impl/Instances
at com.github.houbb.opencc4j.util.ZhConverterUtil.(ZhConverterUtil.java:27)
at org.linghuxiong.poesy.input.TangInput$1.setValues(TangInput.java:57)
at org.springframework.jdbc.core.JdbcTemplate.lambda$batchUpdate$2(JdbcTemplate.java:944)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:617)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:647)
at org.springframework.jdbc.core.JdbcTemplate.batchUpdate(JdbcTemplate.java:936)
at org.linghuxiong.poesy.input.TangInput.save2db(TangInput.java:42)
at org.linghuxiong.poesy.input.TangInput.main(TangInput.java:32)
Caused by: java.lang.ClassNotFoundException: com.github.houbb.heaven.support.instance.impl.Instances
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 8 more

关于部分异体字实际占用两个字符的情况

在实际使用库转换一些古籍文本时,有不少的文字转换失败,实际调试发现,有些异体字如𨦟,其占用两个char作为一个完整意义上的可见字符,而库中源码将字符串转为字符串数组的方式可能会将这种关联断掉,导致转换失败。实际自己的魔改实践发现,java.lang.String#codePointCount方法可以得到一个字符串中所含有的完整【字符】数量,例图二,我想请问您是否有打算兼容这种情况。
image
image

判断繁简体出错

您好,在进行汉语字的繁简体判断时出现问题。
词:寳
isSimple() ---->true

image

这是什么原因呢?

JDK1.7+tomcat7启动错误,提示需要jdk1.8

nested exception is java.lang.UnsupportedClassVersionError: com/github/houbb/paradise/common/util/StringUtil : Unsupported major.minor version 52.0 (unable to load class com.github.houbb.paradise.common.util.StringUtil)
经测试,将paradise-common-1.1.3.jar依赖移出后,可以解决如上错误.

可否去掉代码中对paradise-common-1.1.3.jar包的依赖?

  1. 将StringUtil改为[commons-lang-2.5.jar]的org.apache.commons.lang.StringUtils
  2. 将数组和对象的空判断改为代码的==null和size()>0
  3. 将splitByAnyBlank写到自己的代码中.
    public static String[] splitByAnyBlank(String string) {
    if (StringUtils.isEmpty(string)) {
    return new String[0];
    } else {
    String pattern = "\\s+";
    return string.split(pattern);
    }
    }

基于繁简体词库实现对应的分词算法及相关优化

  1. 自定义分词算法需要完全兼容以前的 api
  2. 移除 jieba 分词 jar 依赖,默认使用自己实现的分词。保留对应的分词实现,但需要用户自己引入 jar。
  3. 提供实现的分词与 jieba 分词的 benchmark,性能优异才发布正式版。(可利用 alpha, beta 进行初期尝试)
  4. 弱化 Bs 引导类及分词的概念,以工具类作为核心。提升用户体验,也便于后期内部优化拓展。
    将原来 Bs 中的方法,全部以工具类的形式支持,废弃 Bs。

第一次繁体转换会非常耗时

我这是Android项目

第一次进行繁体转换的时候,非常耗时,日志打印时间在2-3秒左右,时间根据设备配置会有差别
有没有什么办法可以提前初始化一些必要资源

Logger.i("time__" + System.currentTimeMillis())
ZhConvertBootstrap.newInstance().toTraditional("生命不息,奋斗不止")
Logger.i("time__" + System.currentTimeMillis())

log:
1596423927774
1596423930871

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.