Opencc4j 開源中文繁簡體使用介紹

發表於2024-02-12

Opencc4j

Opencc4j 支援中文繁簡體轉換,考慮到片語級別。

Features 特點

  • 嚴格區分「一簡對多繁」和「一簡對多異」。
  • 完全相容異體字,可以實現動態替換。
  • 嚴格審校一簡對多繁詞條,原則為「能分則不合」。
  • 詞庫和函式庫完全分離,可以自由修改、匯入、擴充套件。
  • 相容 Windows、Linux、Mac 平臺。
  • 支援自定義分詞
  • 支援判斷單個字(詞)是否為簡體/繁體
  • 支援返回字串中簡體/繁體的列表資訊
  • 支援臺灣地區繁簡體轉換

創作緣由

  • OpenCC

OpenCC 的思想非常優秀,做的也特別棒。但是沒有特別為 java 提供的工具。

  • jopencc

jopencc 沒有提供分詞功能。

快速開始

maven 引入

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

api 概覽

核心工具列表如下:

序號工具類簡介
1ZhConverterUtil基礎的繁簡體轉換
2ZhTwConverterUtil臺灣地區的繁簡體轉換

所有的工具類方法具有相同的方法設計,便於記憶。

核心方法如下:

序號api 方法簡介
1toSimple(String)轉為簡體
2toTraditional(String)轉為繁體
3simpleList(String)返回包含的簡體列表
4traditionalList(String)返回包含的繁體列表
5toSimple(char)返回單個漢字對應的所有簡體字列表
6toTraditional(char)返回單個漢字對應的所有繁體字列表
7isSimple(String)是否全部為簡體
8isSimple(char)單個字元是否為簡體
9containsSimple(String)字元中是否為包含簡體
10isTraditional(String)是否全部為繁體
11isTraditional(char)單個字元是否為繁體
12containsTraditional(String)字元中是否為包含繁體
13isChinese(String)是否全部為中文
14isChinese(char)單個字元是否為中文
15containsChinese(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 工具類獲取系統內建的分詞實現。

序號方法準確性效能備註
1defaults()預設分詞形式,暫時為 fastForward 策略
2fastForward()較高fast-forward 分詞策略
3chars()將字串轉換為單個字元列表,一般不建議使用
4huaBan()一般花瓣的結巴分詞策略

花瓣結巴分詞

花瓣結巴分詞在使用時,需要自行引入結巴分詞依賴。

<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: 後續考慮引入更加簡單的實現方式,比如基於文字擴充,不過可擴充套件性沒有介面靈活。

NLP 開源矩陣

pinyin 漢字轉拼音

pinyin2hanzi 拼音轉漢字

segment 高效能中文分詞

opencc4j 中文繁簡體轉換

nlp-hanzi-similar 漢字相似度

word-checker 拼寫檢測

sensitive-word 敏感詞

本文由部落格一文多發平臺 OpenWrite 釋出!