Hiển thị kí tự tiếng Việt chính xác mà không hiển thị mã Unicode

Bạn in ra file rồi đọc lại, rồi in lại ra terminal đúng không? Nếu bạn mở file output bằng text editor thì sẽ thấy chẳng có khác nhau gì cả.

Hoặc nhanh nhất là bạn đổi sang Python 3, Python 2 sắp đến hồi khai tử rồi.

4 Likes

mình xem trên sublimetext thôi, chứ không xem trên terminal, khi lưu thì nó bị như vậy, mình dùng python3

cụ thể là mình đọc ghi file json, không biết có liên gì không?

trên đầu mình có ghi như này:

# -*- coding: utf8 -*-
2 Likes

Bạn đã encode string sang UTF-8 và mở file bằng encoding UTF-8 chưa?

3 Likes

bằng lệnh hay là chỉnh sửa phần mêm đọc file (sublime mình đang dùng) vậy

1 Like

1 Like

Xác nhận là do json nhé bạn. Json không lưu được trực tiếp các kí tự unicode mà phải lưu qua mã.

>>> json.dumps({"id":1, "text":"thử cái đã"})
'{"id": 1, "text": "th\\u1eed c\\u00e1i \\u0111\\u00e3"}'
4 Likes

vậy sự khác nhau là 1 cái đã được mã unicode đã được decode và 1 cái chưa được decode hả bạn.

1 Like

mình có thử search trên mạng, sau khi thêm 2 dòng này thì mình đã làm được:

with open('data_book.json', 'w', encoding='utf-8') as outfile:
	for f in data:
		tmp = f['id'].split("_")
		if(tmp[0] == "BOOK"):
			json.dump(f, outfile, ensure_ascii=False)
			outfile.write('\n')

thêm

encoding='utf-8'
ensure_ascii=False

lúc thì bạn dùng unicode lúc thì bạn dùng utf-8 mình chưa hiểu lắm

1 Like

code trên là mình đang ghi vài file (mình cần write)

2 Likes

ngoài ra bạn giải thích cho mình, tại sao khi bạn dùng là unicode, khi bạn lại dùng là utf-8 vậy?

1 Like

UTF-8 là viết tắt của 8-bit Unicode Transformation Format.

Unicode là…

Thường thì viết kí tự tiếng Việt vào file với encoding UTF-8.

3 Likes

vậy sự khác nhau giữa 2 loại mã utf-8 trên là gì vậy bạn :), mình đọc rồi nhưng chưa biết.

tr\u01b0\u1eddng

trường
1 Like

trường lưu xuống file vậy là đã có thông qua encoding (utf-8 hoặc utf-16 hoặc ucs-2 hoặc utf-32, v.v…)

tr\u01b0\u1eddng là lưu ko có encoding. \u01b0\u1edd là Unicode code point, bạn "\u1edd code point" là ra “LATIN SMALL LETTER O WITH HORN AND GRAVE”

Unicode map mỗi ký tự với 1 số cố định gọi là code point, hiện tại có khoảng hơn 1.1 triệu code point. Các code point này được encode thành n bytes gọi là code value. Mỗi code point được encode thành bao nhiêu byte thì tùy theo encoding gì. Ví dụ:

  • UTF-8 thì các code point được encode thành 1,2,3, hoặc 4 bytes tùy theo giá trị code point đó.
  • UTF-16 thì các code points được encode thành 2 hoặc 4 bytes.
  • UTF-32 thì các code points được encode thành 4 bytes.
  • UCS-2 thì chỉ encode các code points thành đúng 2 bytes, tức là ko lưu trữ được hết 1.1 triêu code points vì 2 bytes chỉ lưu tối đa được 65536 code points mà thôi :V

tuy UCS-2 chỉ lưu được có 65k ký tự nhưng ngoài 65k ký tự này các ký tự khác rất ít khi xài. 65k ký tự đầu tiên này gọi là Basic Multilingual Plane (BMP).

sở dĩ có các encoding này là để tiết kiệm bộ nhớ: lưu trực tiếp code point thì tốn 6 bytes (\uxxxx với x là 1 số hệ 16) hoặc 4 bytes binary (1.1 triệu code points nên xài 32-bit integer), còn lưu nhờ các encoding kia thì tốn ít hơn (1-4 bytes 1 code point)

đừng nhầm lẫn Unicode với các encoding UTF-8 UTF-16 UTF-32 :V Ông nội Windows bị khùng, UCS-2 mà mấy ổng ghi là Unicode nên mới gây nhầm lẫn như vậy. Với người dùng bình thường họ ko biết thì ko sao, MS lừa được họ, còn lập trình viên thì phải biết phân biệt chiêu trò lừa đảo của MS :V :V Unicode ko liên quan gì tới encoding :V

khi lưu:
[ký tự] ----map Unicode----> [code point] ----encode----> [code value] ----write----> [file]

khi đọc:
[file] ----read----> [code value] ----decode----> [code point] ----map Unicode----> [ký tự]

thư viện json của Python 3 có lẽ vì nó sợ user xài bậy :V lưu file ko có encode utf-8 hoặc encode ucs-2 :V :V nên nó mới mặc đình xài \uxxxx như vậy, bảo đảm save/load với open(..., 'w') luôn đúng.

4 Likes

UCS-2 = luôn là 16-bit :smiley: (Windows)
UTF-8 = 8/16/24/32-bit (thông dụng nhất trên web)
UTF-16 = 16-bit || 32-bit :slight_smile:

4 Likes

cám ơn tiền bối, cái gì cũng biết. giờ em mới biết khái niệm ucs-2, có search qua, thì thấy người ta đã bỏ nó rồi. Mà tiền bối viết như trên, em đọc vẫn còn mơ hồ quá.

Nổ não: là một kí tự gồm 2 code point đại diện cho â và dấu sắc :smiley:

3 Likes

Ờ, bỏ rồi!
Nếu xem trong Unikey, bạn sẽ thấy danh sách các Bảng mã, trong đó có:

  • Unicode dựng sẵn. Thông dụng nhất, chuẩn hiện nay.
  • Unicode tổ hợp. Cái UCS-2 này đây.
  • Không nhớ tên, khi gõ sẽ hiện kiểu \xhh hay \uhhhh gì đấy.
  • Vài bảng mã cũ khác (từ thời chưa hỗ trợ Unicode).

Theo trí nhớ!

3 Likes

cái này là tổ hợp :V Combining character gì ấy, 1 cái hại não nữa của Unicode. 1 glyph có thể được ghép lại từ nhiều combining characters :V Do tiếng Việt số glyph hạn chế nên người ta gán code points luôn cho mấy chữ tiếng Việt, nhưng vẫn xài glyph ghép được :V

ghép 1 dấu sắc đã là gì :V :V https://lingojam.com/ZalgoText

d̴̖̘͖́̉̂͝͠͝a̶̤̓̇͠͠ý̴̠͚̤͇̈́̓̓̑̑ͅn̴̡͖͔̪̐̆̉̃͊̒͒̎h̷̨̢͔̜̼͕̙͖̏̅ä̵̧̦̟͍̲͔́͛̓̅̔̀͝͠ͅu̵̧̧̯͖̮͔̽̈́̔̈́̔̐͘͜h̸̠͍̿͆̇͆̏̽̈́̀o̶̠̦̱̾̊͛̏c̴̫͈̀̅́̃

con người viết chữ có ghép chữ lại với nhau thành ra Unicode cũng phải có vụ ghép này. Ghép đã rồi lại thấy từ ghép ít quá cho làm code point riêng luôn thành ra tiếng Việt có 2 cách viết ghép chữ và dấu và cách xài trực tiếp chữ có dấu :V

4 Likes

Các bạn có thể dùng cách này:

with open(Save_yml_path, 'w',   encoding='utf-8') as yaml_file:
    yaml.dump(Data_Dict_CoTiengViet, yaml_file, default_flow_style=False, allow_unicode=True, encoding='utf-8')
1 Like

A post was merged into an existing topic: Topic lưu trữ các post off-topic - version 3

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?