2017-07-02 45 views
5

Tôi đang làm việc để tải danh sách các ký tự biểu tượng cảm xúc trong tập lệnh python 3.6 đơn giản. Cấu trúc YAML về cơ bản là như sau:Tải các ký tự đặc biệt với PyYaml

-  
- 
- 

script python của tôi trông như thế này:

import yaml 
f = open('emojis.yml') 
EMOJIS = yaml.load(f) 
f.close() 

Tôi nhận được ngoại lệ sau đây:

yaml.reader.ReaderError: unacceptable character #x001d: special characters are not allowed in "emojis.yml", position 2 

Tôi đã thấy các tùy chọn allow_unicode=True nhưng điều đó dường như chỉ có sẵn cho yaml.dump. Dường như mọi người gặp sự cố với các vấn đề tương tự trong Python2, nhưng vì tất cả các chuỗi phải là unicode, tôi đang gặp khó khăn trong việc tìm ra lý do tại sao điều này không hoạt động.

Tôi cũng đã thử gói biểu tượng cảm xúc của mình trong dấu ngoặc kép và sử dụng hàm tạo của khách hàng cho 'tag: yaml.org, 2002: str'. Constructor tùy chỉnh của tôi là không bao giờ thậm chí hit có lẽ vì lib yaml là không nhận ra biểu tượng cảm xúc của tôi là có loại chuỗi. Tôi cũng quan sát hành vi tương tự khi tôi xác định biểu tượng cảm xúc của mình trực tiếp dưới dạng chuỗi trong nguồn.

Có cách nào để tải tệp yaml chứa biểu tượng cảm xúc bằng PyYAML không?

+1

Tôi không nghĩ PyYAML hỗ trợ SMP chút nào. –

+1

@ IgnacioVazquez-Abrams, tôi xin lỗi, không có chuyên gia unicode nào. Bởi SMP, bạn có nghĩa là máy bay đa ngôn ngữ bổ sung? SMP có hỗ trợ biểu tượng cảm xúc không? –

+0

@QuinnStearns SMP là [máy bay Unicode bổ sung 1] (https://en.wikipedia.org/wiki/Plane_%28Unicode%29#Overview) và mặt phẳng đó bao gồm [biểu tượng cảm xúc] đó (https: //en.wikipedia. org/wiki/Emoticons_% 28Unicode_block% 29). PyYAML xem xét những thứ không thể in được dựa trên một bài kiểm tra dễ sửa đổi. Sự phát triển chính của PyYAML dừng lại lâu trước khi các biểu tượng cảm xúc được giới thiệu vào năm 2010 (tức là trong Unicode 6.0 trở lên), cũng là lý do PyYAML không hỗ trợ chuẩn YAML 1.2 mới nhất (2009). Cách giải quyết đơn giản là xác định lại quy tắc đối sánh char unicode có thể in. – Anthon

Trả lời

2

Bạn nên nâng cấp lên ruamel.yaml (từ chối trách nhiệm: Tôi là tác giả của gói đó), trong đó có này, và nhiều vấn đề từ lâu PyYAML khác, cố định:

import sys 
from ruamel.yaml import YAML 

yaml = YAML() 

with open('emojis.yml') as fp: 
    idx = 0 
    for c in fp.read(): 
     print('{:08x}'.format(ord(c)), end=' ') 
     idx += 1 
     if idx % 4 == 0: 
      print() 

with open('emojis.yml') as fp: 
    data = yaml.load(fp) 
yaml.dump(data, sys.stdout) 

cho:

0000002d 00000020 0001f642 0000000a 
0000002d 00000020 0001f601 0000000a 
0000002d 00000020 0001f62c 0000000a 
['', '', ''] 

Nếu bạn thực sự phải gắn bó với PyYAML, bạn có thể làm:

import yaml.reader 
import re 

yaml.reader.Reader.NON_PRINTABLE = re.compile(
    u'[^\x09\x0A\x0D\x20-\x7E\x85\xA0-\uD7FF\uE000-\uFFFD\U00010000-\U0010FFFF]') 

để thoát khỏi lỗi.


Bắt đầu với phiên bản 0.15.16, ruamel.yaml bây giờ cũng bãi tất cả các máy bay bổ sung Unicode mà không quay trở lại \Uxxxxxxxx (kiểm soát trong API mới qua .unicode_supplementary, và tùy thuộc vào allow_unicode).

3

này có vẻ là một lỗi trong pyyaml, một cách giải quyết là sử dụng trình tự thoát của họ:

$ cat test.yaml 
- "\U0001f642" 
- "\U0001f601" 
- "\U0001f62c" 

$ python 
... 
>>> yaml.load(open('test.yaml')) 
['', '', ''] 
+1

Aghhhh rực rỡ! Tại sao không nghĩ về điều đó !? Cảm ơn bạn! –