2011-01-13 108 views
16

在Ruby 1.8.7中給定一個字符串(沒有使用\ p {}支持Unicode屬性的真棒Oniguruma正則表達式引擎),我希望能夠確定該字符串是否包含一個或多箇中文,日文或韓文字符;即如何在Ruby中檢測字符串中的某些Unicode字符?

class String 
    def contains_cjk? 
    ... 
    end 
end 

>> '日本語'.contains_cjk? 
=> true 
>> '광고 프로그램'.contains_cjk? 
=> true 
>> '艾弗森將退出籃壇'.contains_cjk? 
=> true 
>> 'Watashi ha bakana gaijin desu.'.contains_cjk? 
=> false 

我懷疑這會歸結到如果任何字符串中的字符都在Unihan CJKV Unicode blocks看到,但我想這是值得一問,如果有人在Ruby中的現有解決方案的認識。

+0

你使用Ruby 1.9的版本,或者只是一箇舊版本不不錯的Unicode支持正則表達式?如果你使用1.9,你應該可以訪問(一些)Unicode屬性,比如'\ p {InCJKUnifiedIdeographs}'或甚至可以'\ p {Han}'。 – tchrist

+0

1.8.7沒有Oniguruma;更新了問題。 –

回答

9

由於我的Ruby 1.8.7的約束,這是我能做的最好的:

class String 
    CJKV_RANGES = [ 
     (0xe2ba80..0xe2bbbf), 
     (0xe2bfb0..0xe2bfbf), 
     (0xe38080..0xe380bf), 
     (0xe38180..0xe383bf), 
     (0xe38480..0xe386bf), 
     (0xe38780..0xe387bf), 
     (0xe38880..0xe38bbf), 
     (0xe38c80..0xe38fbf), 
     (0xe39080..0xe4b6bf), 
     (0xe4b780..0xe4b7bf), 
     (0xe4b880..0xe9bfbf), 
     (0xea8080..0xea98bf), 
     (0xeaa080..0xeaaebf), 
     (0xeaaf80..0xefbfbf), 
    ] 

    def contains_cjkv? 
    each_char do |ch| 
     return true if CJKV_RANGES.any? {|range| range.member? ch.unpack('H*').first.hex } 
    end 
    false 
    end 
end 


strings = ['日本', '광고 프로그램', '艾弗森將退出籃壇', 'Watashi ha bakana gaijin desu.'] 
strings.each {|s| puts s.contains_cjkv? } 

#true 
#true 
#true 
#false 

漂亮hacktacular,但它的作品。它實際上也檢測各種印度語腳本,所以它應該可能真的被稱爲contains_asian?也許我應該爲其他可憐的I18N黑客做好準備,並堅持使用Ruby 1.8。

+0

我認爲其他人可能會發現它有幫助。 – Geo

+0

我也有一個項目堅持1.8。這個解決方案對我不起作用,但我改編了另一個Stack Overflow線程的解決方案 - 請參閱我的答案。 –

1

我寫了一個小的寶石,包起來的做法,steenslag的回答以上:

https://github.com/jpatokal/script_detector

它也可以採取在日語,韓語,簡體中國和中國傳統區分一刺,雖然由於漢族統一的複雜性,它只能在大塊文字上可靠地工作。

0

的Ruby 1.8的解決方案基於this code和使用喬什Glover的解決方案API在此線程:

class String 
    CJKV_RANGES = [ 
    (0x4E00..0x9FFF), 
    (0x3400..0x4DBF), 
    (0x20000..0x2A6DF), 
    (0x2A700..0x2B73F), 
    ] 

    def contains_cjkv? 
    unpack("U*").any? { |char| 
     CJKV_RANGES.any? { |range| range.member?(char) } 
    } 
    end 
end 
相關問題