0

Ruby 1.9.3 からファイル名を読み取ると、奇妙な結果が表示されます。たとえば、「Testé.txt」という名前のファイルを含むフォルダーで実行される次のテスト ruby​​ スクリプトを使用します。

#!encoding:UTF-8
def inspect_string s
    puts "Source encoding: #{"".encoding}"
    puts "External encoding: #{Encoding.default_external}"
    puts "Name: #{s.inspect}"
    puts "Encoding: #{s.encoding}"
    puts "Chars: #{s.chars.to_a.inspect}"
    puts "Codepoints: #{s.codepoints.to_a.inspect}"
    puts "Bytes: #{s.bytes.to_a.inspect}"
end

def transform_string s
   puts "Testing string #{s}"
   puts s.gsub(/é/u,'TEST')
end

Dir.glob("./*.txt").each do |f|  

   puts RUBY_VERSION + RUBY_PLATFORM

   puts "Inline string works as expected" 
   s = "./Testé.txt" 
   inspect_string s
   puts transform_string s

   puts "File name from Dir.glob does not" 
   inspect_string f
   puts transform_string f

end

Mac OS X Lion では、次の結果が表示されます。

1.9.3x86_64-darwin11.4.0
Inline string works as expected
Source encoding: UTF-8
External encoding: UTF-8
Name: "./Testé.txt"
Encoding: UTF-8
Chars: [".", "/", "T", "e", "s", "t", "é", ".", "t", "x", "t"]
Codepoints: [46, 47, 84, 101, 115, 116, 233, 46, 116, 120, 116]
Bytes: [46, 47, 84, 101, 115, 116, 195, 169, 46, 116, 120, 116]
Testing string ./Testé.txt
./TestTEST.txt

File name from Dir.glob does not
Source encoding: UTF-8
External encoding: UTF-8
Name: "./Testé.txt"
Encoding: UTF-8
Chars: [".", "/", "T", "e", "s", "t", "e", "́", ".", "t", "x", "t"]
Codepoints: [46, 47, 84, 101, 115, 116, 101, 769, 46, 116, 120, 116]
Bytes: [46, 47, 84, 101, 115, 116, 101, 204, 129, 46, 116, 120, 116]
Testing string ./Testé.txt
./Testé.txt

予想される最後の行は

./TestTEST.txt

返されたエンコーディングは、これが通常の UTF-8 文字列であるにもかかわらず、Unicode を含む正規表現変換が適切に適用されていないことを示しています。

4

2 に答える 2

3

これに対する更新: Ruby 2.2.0 ではString#unicode_normalizeが追加されました。

f.unicode_normalize!

OSX の HFS+ ファイルシステムから返された NFD で分解された文字列を NFC で構成された文字列に変換します。別の正規化が必要な場合は、、、:nfdまたは:nfkcを指定できます。:nfkd

于 2015-01-13T13:13:52.493 に答える
0

これがこれに遭遇した他の人にとって役立つ場合に備えて投稿されました:

Ruby 1.9 および 2.0 は、UTF-8 エンコーディングを使用する場合、合成された UTF-8 文字列を使用しますが、OS から受け取った文字列を変更しません。Mac OS X は、分解された文字列を使用します (UTF-8 の é のような多くの一般的なアクセントは 2 バイトで表示されます)。そのため、ファイル システム メソッドは予期しない文字列形式を返すことがよくあります。これは厳密には UTF-8 ですが、分解された形式です。

これを回避するには、「UTF8-MAC」エンコーディングから UTF-8 に変換して分解する必要があります。

f.encode!('UTF-8','UTF8-MAC')

それらを使用する前に、そうしないと、合成されたネイティブのルビ文字列を使用して、分解された文字列に対してチェックを実行することになる可能性があります。

この動作は、ファイル名に Unicode 文字が含まれるファイルとフォルダーの両方に対する glob などのすべてのファイル システム呼び出しに影響します。

アップルのドキュメント:

http://developer.apple.com/library/mac/#qa/qa1235/_index.html

于 2012-11-02T11:16:02.007 に答える