5

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

The 恐龙 ate 鱼.

由于其中包含汉字文本,因此将被标记如下:

The \language[cn]{恐龙} ate \language[cn]{鱼}.
  • 文档保存为 UTF-8。
  • 中文文本应标明\language[cn]{*}
  • 日文文字应标注\language[ja]{*}
  • 韩文文字应标明\language[ko]{*}
  • 内容永远不会从一行继续到下一行。
  • 如果代码对某些内容是中文、日文还是韩文有疑问,最好默认为中文。

如何根据当前语言标记文本?

4

3 回答 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 물고기.

(另见Detect chinese character using perl?

这是有问题的。Daenyth评论说,例如恐竜被误识别为中文。我发现您不太可能真正使用混合的英语-CJK,并且只是给出了糟糕的示例文本。首先进行词汇分析以区分中文和日文。

于 2012-05-07T14:08:07.287 回答
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]{물고기}.
于 2012-05-07T20:55:39.040 回答
3

虽然韩语不再使用汉字[汉字/汉字],但它们有时仍会弹出。一些日本的正弦图是纯日文的,比如竜,但很多都与简体中文或繁体相同。所以你有点卡住了。所以如果你有一些“汉”字符,你需要看一个完整的句子。如果它有一些平假名/片假名+汉字,那么它是日语的可能性非常高。同样,一堆韩文音节和几个正弦图会告诉你这个句子是韩文的。

那么,如果都是汉化字符,即中文,可以看一下是否有一些字符是简体的:kZVariant 表示一个简体中文字符。哦,kSpecializedSemanticVariant 经常用于日语特定的简化字符。里面和内你可能看起来一样,但第一个是日文,第二个是繁体中文和韩文(韩文以繁体中文为标准)。

我在某处有代码,它为一个代码点返回脚本名称。那会有所帮助。你通过一个句子,看看最后剩下什么。我会把代码放在某个地方。

编辑:代码

http://pastebin.com/e276zn6y

回应以下评论:

上面的这个函数是基于 Unicode.org 提供的数据构建的……虽然我本身不是专家,但我为 Unihan 数据库贡献了很多——而且我碰巧会说 CJK。是的,全部 3。我确实有一些代码可以利用kXXXUnihan 数据库中的属性,但是 A/ 我不知道我们应该为 OP 编写代码,并且 B/ 这需要可能会进行的后勤工作超出了 OP 准备实施的范围。我的建议站得住脚。使用上面的函数,循环一个完整的句子。如果所有代码点都是“Han”(或“Han”+“Latin”),那么很有可能是中文。另一方面,如果结果是“Han”+“Hangul”(可能+“latin”)的混合,那么韩语就不会出错。同样,“汉”和“

快速测试

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

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"

r对象包含每个脚本的出现次数。平假名是最常见的,平假名+片假名 --> 句子的 2/3。

r=guessLanguage("我唔知道,佢講乜話.")
Object
  Common: 2
  Han: 8
  __proto__: Object
"Han"

一个明显的中文案例(在这种情况下是粤语)。

r=guessLanguage("中國이 韓國보다 훨씬 크지만, 꼭 아름다운 나라가 아니다...");
Object
  Common: 11
  Han: 4
  Hangul: 19
  __proto__: Object
"Hangul"

一些汉字,还有很多韩文。一句韩语,肯定的。

于 2012-05-19T17:04:59.603 回答