BYVoid / OpenCC

Conversion between Traditional and Simplified Chinese
https://opencc.byvoid.com/
Apache License 2.0
8.39k stars 975 forks source link

能不能限制某些生僻字转换成类推简化字,影响手机阅读 #217

Open tsauibusato opened 7 years ago

tsauibusato commented 7 years ago

举一例,如 趙孟頫→赵孟𫖯,那个 頫字在安卓默認字體DroidSans下是豆腐,㑮→𫝈,還有更多類似的,不勝枚舉,他們的繁體字是可以正常顯示的,然而簡體有些屬於民間類推簡化,常見字體是不收錄的,能不能把這些字剔除或單獨列出

BYVoid commented 7 years ago

目前沒有這樣的功能,但是簡單的解決方案是過濾掉所有不在UCS2範圍內的字符。

Buernia commented 7 years ago

一点想法: 如果可以实现的话,简繁转换可以控制在《通用规范汉字表》(以下简称为表)的范围内,以防止无限制类推到扩展区简化字造成的豆腐块问题。 (《通用规范汉字表》草案里曾提过表外汉字不再类推,但正式版里没有了,现在很模糊。)

“⿰兆页” 这个字是表内汉字,“⿰亻军” 似乎不是。

另外,安卓最新版本的默认中文字体 Noto Sans CJK 是支持表内的所有汉字的,iOS 的苹方似乎也支持。另据我了解,微软在不远的将来也会支持,并且支持的范围可能还要更广。

tsauibusato commented 7 years ago

苹方并不支持,大部分国产手机上了安卓7.0也没有Noto Sans CJK字体。另外这些字是微软最先支持的。

发自:ZUK Z2 在 奈白不弍 notifications@github.com,2017年3月1日 下午6:37写道:

一点想法: 如果可以实现的话,简繁转换可以控制在《通用规范汉字表》(以下简称为表)的范围内,以防止无限制类推到扩展区简化字造成的豆腐块问题。 (《通用规范汉字表》草案里曾提过表外汉字不再类推,但正式版里没有了,现在很模糊。)

“⿰兆页” 这个字是表内汉字,“⿰亻军” 似乎不是。

另外,安卓最新版本的默认中文字体 Noto Sans CJK 是支持表内的所有汉字的,iOS 的苹方似乎也支持。另据我了解,微软在不远的将来也会支持,并且支持的范围可能还要更广。

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHubhttps://github.com/BYVoid/OpenCC/issues/217#issuecomment-283305110, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AUTHq7WptYrGmOT0bewq5-XzGFCGNVorks5rhUpHgaJpZM4LYhfE.

Buernia commented 7 years ago

苹方并不支持,大部分国产手机上了安卓7.0也没有Noto Sans CJK字体。另外这些字是微软最先支持的。

苹方我了解不多,因为我知道苹方里有 “⿰车柔” 字,所以才会如此推断。 Noto Sans CJK 我自认为普及率还是不低的。 微软到目前为止只有支持到扩展 B 区(宋体 ExtB 和新细明体 ExtB),C、D、E 区汉字没有相应字体。

tsauibusato commented 7 years ago

然而noto sans cjk在程序员那里普及率是不低,然而一众国产手机并无此字体。即使是上了安卓7.0也无。还是要考虑实际嘛

发自:ZUK Z2 在 奈白不弍 notifications@github.com,2017年4月10日 上午10:36写道:

苹方并不支持,大部分国产手机上了安卓7.0也没有Noto Sans CJK字体。另外这些字是微软最先支持的。

苹方我了解不多,因为我知道苹方里有 “⿰车柔” 字,所以才会如此推断。 Noto Sans CJK 我自认为普及率还是不低的。 微软到目前为止只有支持到扩展 B 区(宋体 ExtB 和新细明体 ExtB),C、D、E 区汉字没有相应字体。

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHubhttps://github.com/BYVoid/OpenCC/issues/217#issuecomment-292835933, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AUTHqyfJwrgR0YjH4dH9oYJ1aH2rbvUyks5ruZWNgaJpZM4LYhfE.

danny0838 commented 4 years ago

可否加上一個 regex 指令參數過濾輸出候選?比如指定 ^[\u0000-\uFFFF]+$ 以後,繡 𰬩 绣 過濾後只考慮 繡 绣;又如 繨 𫄤 過濾後沒有符合的輸出,那就忽略對 的繁轉簡。

如果對已編譯的字典檔過濾輸出會嚴重影響轉換效能,或許可考慮另一方案是將此參數用於編譯階段,亦即用此參數改變編譯出的字典檔。

sgalal commented 4 years ago

可否加上一個 regex 指令參數過濾輸出候選?比如指定 ^[\u0000-\uFFFF]+$ 以後,繡 𰬩 绣 過濾後只考慮 繡 绣;又如 繨 𫄤 過濾後沒有符合的輸出,那就忽略對 的繁轉簡。

如果對已編譯的字典檔過濾輸出會嚴重影響轉換效能,或許可考慮另一方案是將此參數用於編譯階段,亦即用此參數改變編譯出的字典檔。

沒必要這麼麻煩,直接修改轉換詞庫,刪除這些詞即可。

danny0838 commented 4 years ago

@sgalal 原來的思路就是讓使用者方便在不須改動詞庫下使用,較為方便。

而且這問題也可能影響轉換表的審訂。目前轉換表尚未收錄 Unicode Ext-E 以上的簡繁轉換組合,如果把這些轉換全加入,甚至有些 UCS-2 的字會被轉換到 Ext-G,比如「儅」=>「𰁸」,Ext-G 絕大部分擴展字集都還沒有支援,這樣真的無所謂嗎?不曉得目前的轉換表在字集上有沒有什麼審訂標準?

buganini commented 4 years ago

這應該不屬於繁簡轉換的問題,而是transliteration,應該僅作為顯示前的filter

project chvar處理的議題包含異體字及transliteration及搜尋用途的相容標準化,以他的資料是可以把超出BMP範圍的codepoint給出適用CJK不同地區的代用字,不過資料主要只有台灣CCCII的異體字資料和中國的第一批簡體字表,另外加一些人工維護的資料,看來簡體資料是不太完善。

https://bsdconv.io/chvar/lookup#%E9%A9%9B

danny0838 commented 4 years ago

除了前述用支援Regex限定輸出字集的方式以外,另一個可考慮的方案是分割碼表,也就是把非通用規範漢字表的簡繁轉換移到另一個轉換表,然後把各簡繁轉換方案分成「繁轉簡」及「繁轉簡(含類推簡化)」兩個版本,比如 t2s.json 分成 t2s.json 和 t2sx.json。

可以考察下中國的實際使用情形,也就是對於表外漢字,一般是類推簡化或者不類推簡化,或是視場合不同而有不同做法。如果一般都是類推簡化,那就不用分表了;其他兩種情況應該都可以分表處理以滿足不同需求。

簡轉繁的部分,理論上全部轉不會有問題,但如果繁轉簡要分表,為校訂方便,建議簡轉繁也做相應的分表,不過轉換方案應該就不用特別區分「簡轉繁」和「簡轉繁(含類推簡化)」了。

danny0838 commented 4 years ago

不過這裡有個問題:《通用規範漢字表》裡面有不少字是 SMP 字元,例如「𬸣」、「𬶨」都是 Ext-E 的字;而它們對應的繁體字都是 BMP 字。如果只是把轉換表分成「規範漢字」和「規範漢字+類推簡化字」,可能無法完全達到「避免把生僻字轉成無法閱讀的字」的目的。

但想一想似乎又沒那麼嚴重,一來這些 BMP/SMP 字本身不常見,二來一旦文本有那些字,用到 Ext-E 也是按照《通用規範漢字表》使用國家規範字的合理結果罷了,不能說是錯誤。

如果真的在意這問題,就按前面說的實做下支援篩選輸出字集吧。

danny0838 commented 4 years ago

實做了一下把規範簡化與類推簡化分離,比想象中簡單很多,準備好《通用規範漢字表》後寫幾行程式就解決了。實做示例可以參考這裡最後 2 個 commits。

因為要跑程式且很容易有合併衝突的問題,請大家先評估下,等確定要實做我再 patch 到目前版本發 PR。

fuxin052 commented 1 year ago

提供个思路, 先转化, 再换回来, 以python为例

import opencc
converter_opencc = opencc.OpenCC('tw2s.json')
def converter(s:str):
    ret = ""
    temp = converter_opencc.convert(s)
    for idx,word in enumerate(temp):
        if ord(word) > 0xffff: # 这里判断是范围外的字就用原字
            ret += s[idx]
        else:
            ret += word
    return ret