2015-06-11 19 views
7

Có khá nhiều sự trợ giúp xung quanh điều này, nhưng tôi vẫn còn bối rối.Độ dài Python của sự nhầm lẫn chuỗi unicode

Tôi có một chuỗi unicode như thế này:

title = u'test' 
title_length = len(title) #5 

Nhưng! Tôi cần len (tiêu đề) để được 6. Các khách hàng mong đợi nó được 6 bởi vì họ dường như đếm theo một cách khác với tôi làm trên phụ trợ.

Như một cách giải quyết, tôi đã viết trợ giúp nhỏ này, nhưng tôi chắc chắn nó có thể được cải thiện (với đủ kiến ​​thức về mã hóa) hoặc có lẽ nó thậm chí còn sai.

title_length = len(title) + repr(title).count('\\U') #6 

1. Có cách nào tốt hơn để nhận được độ dài là 6? :-)

Tôi giả sử tôi (Python) đang tính số ký tự unicode là 5. Các khách hàng đang tính số byte?

2. Logic của tôi có bị ngắt đối với các ký tự unicode khác cần 4 byte không?

Chạy Python 2,7 ucs4.

+3

Khách hàng tính các cặp thay thế UTF-16. –

+0

Khi tôi thử chạy hai dòng này, nó cho thấy chiều dài là 6. – ssundarraj

+1

@ssundarraj: xem câu trả lời của tôi; bạn đang chạy bản dựng Python 2 UCS2. Sử dụng Python 3.3 trở lên hoặc tự tạo bản dựng UCS4. –

Trả lời

6

Bạn có 5 codepoints. Một trong những điểm mã hóa nằm ngoài Basic Multilingual Plane có nghĩa là mã hóa UTF-16 cho các điểm mã hóa has to use two code units for the character.

Nói cách khác, khách hàng dựa vào chi tiết triển khai và đang làm điều gì đó sai. Họ phải đếm mã điểm, không phải mã đơn vị. Có một số nền tảng mà điều này xảy ra khá thường xuyên; Python 2 UCS2 xây dựng là một trong những như vậy, nhưng các nhà phát triển Java thường quên đi sự khác biệt, cũng như Windows API.

Bạn có thể mã hóa văn bản thành UTF-16 và chia số byte thành hai (mỗi đơn vị mã UTF-16 là 2 byte). Chọn utf-16-le hoặc utf-16-be biến thể không bao gồm BOM trong chiều dài:

title = u'test' 
len_in_codeunits = len(title.encode('utf-16-le')) // 2 

Nếu bạn đang sử dụng Python 2 (và xét xử của các u tiền tố vào chuỗi bạn cũng có thể được), đưa vào tài khoản là có 2 hương vị khác nhau của Python, tùy thuộc vào cách bạn xây dựng nó. Tùy thuộc vào công tắc cấu hình thời gian xây dựng, bạn sẽ có bản dựng UCS-2 hoặc UCS-4; người cũ sử dụng người thay thế là nội bộ cũng là và chiều dài giá trị title của bạn cũng sẽ là 6 ở đó. Xem Python returns length of 2 for single Unicode character string.

+0

Khách hàng thực sự là Java, làm cách nào bạn biết họ đang tính các cặp thay thế UTF-16? Nó có thể không phải là UTF-8 hoặc UTF-32 không? Tôi có thể chắc chắn rằng họ là * luôn luôn * đếm 2 codeunits, depeding trên codepoint nó có thể được nhiều hơn? Phương pháp đếm của bạn trông thực sự thanh lịch hơn. :-) Cảm ơn rất nhiều vì lời giải thích tuyệt vời này! – kev

+0

Số đếm sẽ cực kỳ khác nếu chúng đếm các đơn vị mã trong một codec UTF khác (8 trong UTF-8 và 5 cho UTF-32). Có, UTF-16 hoặc sử dụng một hoặc hai đơn vị mã, luôn luôn, xem liên kết Wikipedia trong câu trả lời của tôi.Mã Java có thể được sửa; xem [JSR-204] (https://jcp.org/en/jsr/detail?id=204) và phương thức [codePointCount() '(http://docs.oracle.com/javase/7/ tài liệu/api/java/lang/String.html # codePointCount (int,% 20int)). –

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