2012-05-07 15 views
5

Tôi có một tệp, file1.txt, có chứa văn bản bằng tiếng Anh, tiếng Trung, tiếng Nhật và tiếng Hàn. Để sử dụng trong bối cảnh, tôi cần phải đánh dấu từng vùng văn bản trong tập tin theo ngôn ngữ, ngoại trừ tiếng Anh, và đầu ra một tập tin mới, ví dụ, đây là một dòng mẫu:Làm cách nào để đánh dấu tất cả văn bản CJK trong tài liệu?

The 恐龙 ate 鱼. 

Vì đây chứa văn bản trong chữ Hán, điều này sẽ được đánh dấu như thế này: Tài liệu

The \language[cn]{恐龙} ate \language[cn]{鱼}. 
  • được lưu lại dưới dạng UTF-8.
  • Văn bản tiếng Trung phải được đánh dấu \language[cn]{*}.
  • Văn bản bằng tiếng Nhật phải được đánh dấu \language[ja]{*}.
  • Văn bản bằng tiếng Hàn phải được đánh dấu \language[ko]{*}.
  • Nội dung không bao giờ tiếp tục từ dòng này sang dòng khác.
  • Nếu mã không bao giờ nghi ngờ về việc liệu có gì đó là tiếng Trung, tiếng Nhật hay tiếng Hàn hay không thì tốt nhất là nếu nó là tiếng Trung mặc định.

Tôi làm cách nào để đánh dấu văn bản theo ngôn ngữ hiện tại?

+0

Bạn sẽ xác định xem một nhân vật cụ thể có phải là tiếng Trung hay tiếng Nhật không? Họ chia sẻ nhiều nhân vật. – Daenyth

+0

Nếu ba ngôn ngữ không có mặt trong Unicode, thì tôi sẽ đơn giản hóa câu hỏi của tôi để chỉ đánh dấu mọi thứ từ CJK thành '\ language [cn] {*}'. – Village

+1

Nó phức tạp hơn thế. 3 ngôn ngữ chia sẻ các điểm ký tự (mã số), nhưng không nhất thiết phải là glyph (biểu diễn đồ họa của ký tự). Hãy xem Câu hỏi thường gặp về Unicode CJK http://unicode.org/faq/han_cjk.htm – mirod

Trả lời

6

Một thuật toán thô:

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

(Xem thêm Detect chinese character using perl?)

Có những vấn đề với điều đó. Daenyth nhận xét, ví dụ:恐 竜 bị xác định sai là tiếng Trung. Tôi thấy không chắc bạn đang thực sự làm việc với tiếng Anh-CJK hỗn hợp, và chỉ đưa ra văn bản ví dụ xấu. Thực hiện phân tích từ vựng trước để phân biệt tiếng Trung với tiếng Nhật.

+0

Làm cách nào để sử dụng tập lệnh này để chỉnh sửa tệp? – Village

5

Tôi muốn cung cấp giải pháp Python. Không có vấn đề gì ngôn ngữ, nó được dựa trên thông tin Unicode Script (từ cơ sở dữ liệu Unicode, aka UCD). Perl có UCD khá chi tiết so với Python.
Python không có thông tin Script được mở trong mô-đun "unicodedata" của nó. Nhưng ai đó đã thêm nó tại đây https://gist.github.com/2204527 (nhỏ và hữu ích). Triển khai của tôi dựa trên nó. BTW, nó không phải là không gian nhạy cảm (không cần bất kỳ phân tích từ vựng).

# 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 

Các Output là:

$ 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]{물고기}. 
+0

Tôi làm cách nào để sử dụng tập lệnh này để chỉnh sửa tệp? – Village

3

Trong khi Hàn Quốc không sử dụng nhiều sinograms [漢字/Kanji] nữa, họ vẫn thỉnh thoảng bật lên. Một số chữ nhật Nhật Bản chỉ là tiếng Nhật, giống như 竜, nhưng nhiều chữ cái giống hệt với tiếng Trung Giản thể hoặc Truyền thống. Vì vậy, bạn đang bị mắc kẹt. Vì vậy, bạn cần phải nhìn vào một câu đầy đủ nếu bạn có một số ký tự "Han". Nếu nó có một số hiragana/katakana + kanji, xác suất là rất cao, đó là tiếng Nhật. Tương tự như vậy, một bó của hangul âm tiết và một vài chữ lồng sẽ cho bạn biết câu đó bằng tiếng Hàn.

Sau đó, nếu đó là tất cả các ký tự Hán, nghĩa là tiếng Trung, bạn có thể xem liệu một số ký tự có được đơn giản hóa hay không: kZVariant biểu thị một từ tiếng Trung giản thể. Oh, và kSpecializedSemanticVariant rất thường được sử dụng cho các ký tự được đơn giản hóa của Nhật Bản.内 và 內 có thể trông giống như bạn, nhưng thứ nhất là tiếng Nhật, tiếng Trung phồn thể và tiếng Hàn thứ hai (tiếng Hàn sử dụng tiếng Trung phồn thể).

Tôi có mã ở đâu đó trả về, cho một điểm mã, tên tập lệnh. Điều đó có thể giúp ích. Bạn đi qua một câu, và xem những gì còn lại ở cuối. Tôi sẽ đưa mã lên đâu đó.

EDIT: mã

http://pastebin.com/e276zn6y

Để đối phó với những nhận xét dưới đây:

Chức năng này trên được xây dựng dựa trên dữ liệu được cung cấp bởi Unicode.org ... Trong khi không phải là một chuyên gia mỗi lần, tôi đóng góp khá nhiều cho cơ sở dữ liệu Unihan - và tôi tình cờ nói được CJK. Có, tất cả 3. Tôi có một số mã tận dụng lợi thế của các thuộc tính kXXX trong cơ sở dữ liệu Unihan, nhưng A/Tôi không biết chúng tôi được yêu cầu viết mã cho OP và B/nó sẽ yêu cầu hậu cần có thể vượt xa những gì mà OP sẵn sàng thực hiện. Lời khuyên của tôi là viết tắt. Với hàm ở trên, lặp qua một câu đầy đủ. Nếu tất cả các codepoints là "Han", (hoặc "Han" + "Latin"), rất có thể là cao của Trung Quốc. Nếu mặt khác, kết quả là một kết hợp của "Han" + "Hangul" (+ "latin" có thể) bạn không thể đi sai với Hàn Quốc. Tương tự như vậy, một kết hợp của "Han" và "Katakana"/"Hiragana" bạn có tiếng Nhật.

một thử nghiệm nhanh

Một số mã để được sử dụng với chức năng tôi liên kết với trước đó.

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

Một số xét nghiệm:

r=guessLanguage("外人だけど、日本語をペラペラしゃべるよ!"); 
Object 
    Common: 2 
    Han: 5 
    Hiragana: 9 
    Katakana: 4 
    __proto__: Object 
"Hiragana" 

Đối tượng r chứa số lần xuất hiện của mỗi kịch bản. Hiragana là thường xuyên nhất, và Hiragana + Katakana -> 2/3 câu.

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

Trường hợp hiển nhiên của tiếng Trung (tiếng Quảng Đông trong trường hợp này).

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

Một số ký tự Han và toàn bộ Hangul. Một câu tiếng Hàn, chắc chắn.

Các vấn đề liên quan