如何在文档中标记所有的CJK文本?

5

我有一个文件,名为file1.txt,其中包含英文、中文、日文和韩文。为了在ConTeXt中使用,我需要根据语言标记文件中的每个文本区域,但不包括英文,并输出新文件。例如,这是一行示例:

The 恐龙 ate 鱼.

由于这段文本包含中文字符,因此会被标记为:

The \language[cn]{恐龙} ate \language[cn]{鱼}.
  • 文档以UTF-8格式保存。
  • 中文文本应标记为\language[cn]{*}
  • 日语文本应标记为\language[ja]{*}
  • 韩语文本应标记为\language[ko]{*}
  • 内容不会跨越多行。
  • 如果代码对于某些文本无法确定其是否为中文、日语或韩语,则最好将其默认为中文。

如何根据所用语言标记文本?


你如何确定一个特定的字符是中文还是日文?它们共享许多字符。 - Daenyth
如果这三种语言在Unicode中没有位置,那么我将简化我的问题,只将所有内容从CJK标记到\language[cn]{*} - Village
1
这比那更加复杂。这3种语言共享字符点(数字代码),但不一定共享字形(字符的图形表示)。请参阅Unicode CJK FAQ http://unicode.org/faq/han_cjk.htm。 - mirod
这可能会有用:https://dev59.com/W3E85IYBdhLWcg3wikEu - Daenyth
这可能是一个虚拟方法,但比没有好:只需根据符号代码范围映射语言,它们应该在Unicode表中固定。 - ArtMat
http://en.wikipedia.org/wiki/CJK_Unified_Ideographs - simbabque
3个回答

6
一个简单的算法:
use 5.014;
use utf8;
while (<DATA>) {
    s
        {(\p{Hangul}+)}
        {\\language[ko]{$1}}g;
    s
        {(\p{Hani}+)}
        {\\language[zh]{$1}}g;
    s
        {(\p{Hiragana}+|\p{Katakana}+)}
        {\\language[ja]{$1}}g;
    say;
}

__DATA__
The 恐龙 ate 鱼.
The 恐竜 ate 魚.
The キョウリュウ ate うお.
The 공룡 ate 물고기.

(另请参见使用perl检测中文字符?

这有问题。 Daenyth 评论说例如恐竜被错误地标识为中文。我认为你很可能不是真的在处理混合英语-CJK,只是提供了错误的示例文本。首先执行词法分析以区分中文和日文。


5
我可以提供一个Python解决方案。无论使用哪种语言,都基于Unicode脚本信息(来自Unicode数据库,也称为UCD)。与Python相比,Perl具有相当详细的UCD。
Python的"unicodedata"模块没有打开任何脚本信息。但是,有人在这里https://gist.github.com/2204527上添加了它(微小而实用)。我的实现基于它。顺便说一下,它不区分空格(不需要任何词法分析)。
    # coding=utf8
    import unicodedata2
    text=u"""The恐龙ate鱼.
    The 恐竜ate 魚.
    Theキョウリュウ ate うお.
    The공룡 ate 물고기. """

    langs = {
    'Han':'cn',
    'Katakana':'ja',
    'Hiragana':'ja',
    'Hangul':'ko'
    }

    alist = [(x,unicodedata2.script_cat(x)[0]) for x in text]
    # Add Last
    alist.append(("",""))
    newlist = []
    langlist = []
    prevlang = ""
    for raw, lang in alist:
        if prevlang in langs and prevlang != lang:
            newlist.append("\language[%s]{" % langs[prevlang] +"".join(langlist) + "}")
            langlist = []

        if lang not in langs:
            newlist.append(raw)
        else:                      
            langlist.append(raw)
        prevlang = lang

    newtext = "".join(newlist)
    print newtext

输出结果为:
    $ python test.py 
    The\language[cn]{恐龙}ate\language[cn]{鱼}.
    The \language[cn]{恐竜}ate \language[cn]{魚}.
    The\language[ja]{キョウリュウ} ate \language[ja]{うお}.
    The\language[ko]{공룡} ate \language[ko]{물고기}.

3
虽然现代韩语不再使用太多汉字,但有时仍会出现一些。一些日本汉字是纯粹的日本汉字,例如“竜”,但许多汉字与简体中文或繁体中文相同。所以你可能会有些困惑。如果你看到了一些汉字,需要查看整个句子。如果有一些平假名/片假名和汉字混合,很有可能是日语。同样,一堆韩文音节和几个汉字将告诉你这句话是韩语。
然后,如果全是汉字,即中文,你可以看看其中是否有一些简化的字符:kZVariant表示一个简体中文字符。哦,而kSpecializedSemanticVariant经常用于特定的日语简化字符。内和內可能看起来一样,但前者是日语,后者是繁体中文和韩语(韩语使用繁体中文作为标准)。
我有一些代码可以返回一个代码点的脚本名称。这可能会有所帮助。你可以遍历一句话,然后看最后剩下了什么。我会把代码放在某个地方。
编辑:代码

http://pastebin.com/e276zn6y

针对下面的评论:

上述功能是基于Unicode.org提供的数据构建的......虽然我并不是一个专家,但我对Unihan数据库做出了很大的贡献 - 我碰巧会说CJK。是的,全部三种语言。我有一些利用Unihan数据库中的kXXX属性的代码,但A /我不知道我们应该为OP编写代码,B /它需要一种可能超出OP准备实施的物流。我的建议仍然有效。使用上述功能,循环遍历整个句子。如果所有代码点都是“Han”(或“Han” +“Latin”),那么它很可能是中文。另一方面,如果结果是“Han” +“Hangul”(+“latin”可能),则您可以肯定是韩国语。同样,混合使用“Han”和“Katakana” /“Hiragana”,您就有日语。

快速测试

一些代码可与我之前链接的函数一起使用。

function guessLanguage(x) {
  var results={};
  var s='';
  var i,j=x.length;
  for(i=0;i<j;i++) {
    s=scriptName(x.substr(i,1));
    if(results.hasOwnProperty(s)) {
      results[s]+=1;
    } else {
      results[s]=1;
    }
  }
  console.log(results);
  mostCount=0;
  mostName='';
  for(x in results) {
    if (results.hasOwnProperty(x)) {
      if(results[x]>mostCount) {
        mostCount=results[x];
        mostName=x;
      }
    }
  }
  return mostName;
}

一些测试:
r=guessLanguage("外人だけど、日本語をペラペラしゃべるよ!");
Object
  Common: 2
  Han: 5
  Hiragana: 9
  Katakana: 4
  __proto__: Object
"Hiragana"
对象包含每个脚本的出现次数。平假名最频繁,平假名+片假名占句子的2/3。
r=guessLanguage("我唔知道,佢講乜話.")
Object
  Common: 2
  Han: 8
  __proto__: Object
"Han"

一个明显的中文案例(在这种情况下是广东话)。
r=guessLanguage("中國이 韓國보다 훨씬 크지만,  아름다운 나라가 아니다...");
Object
  Common: 11
  Han: 4
  Hangul: 19
  __proto__: Object
"Hangul"

一些汉字和大量的韩文字符。毫无疑问是一个韩文句子。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接