2017-07-02 75 views
5

Pracuję nad ładowaniem listy znaków emoji w prostym skrypcie python 3.6. Struktura YAML jest zasadniczo w następujący sposób:Ładowanie znaków specjalnych za pomocą PyYaml

-  
- 
- 

Mój skrypt python wygląda następująco:

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

Dostaję następujący wyjątek:

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

widziałem opcję allow_unicode=True ale to wydaje się być dostępne tylko dla yaml.dump. Wygląda na to, że ludzie mieli problemy z podobnymi problemami w Python2, ale ponieważ wszystkie napisy powinny być w Unicode, mam problem z ustaleniem, dlaczego to nie działa.

Próbowałem także owijać moje emotikony w cudzysłowy i używać konstruktora klienta dla "tag: yaml.org, 2002: str". Mój niestandardowy konstruktor nigdy nie jest nawet trafiony, ponieważ lib yaml nie rozpoznaje mojego emoji jako typu string. Obserwuję też to samo zachowanie, gdy definiuję moje emoji bezpośrednio jako ciąg w źródle.

Czy istnieje sposób na załadowanie pliku yaml zawierającego emotikony za pomocą PyYAML?

+1

Nie sądzę, że PyYAML w ogóle obsługuje SMP. –

+1

@ Ignacio Vaazquez-Abrams, przepraszam, nie ma eksperta od unicode. Przez SMP, masz na myśli dodatkowy wielojęzyczny samolot? Czy w SMP zdefiniowano obsługę emoji? –

+0

@QuinnStearns SMP to [dodatkowa płaszczyzna Unicode 1] (https://en.wikipedia.org/wiki/Plane_%28Unicode%29#Overview), a samolot obejmuje te [emotikony] (https: //en.wikipedia. org/wiki/Emoticons_% 28Unicode_block% 29). PyYAML uważa te niedrukowalne na podstawie testu łatwego do modyfikacji. Główny rozwój PyYAML został zatrzymany na długo przed wprowadzeniem emotikonów w 2010 r. (Tj. W Unicode 6.0 i późniejszych), a także powodem, dla którego PyYAML nie obsługuje najnowszego standardu YAML 1.2 (2009). Prostym rozwiązaniem jest przedefiniowanie reguły drukowania znaków unicode do drukowania. – Anthon

Odpowiedz

2

należy uaktualnić do ruamel.yaml (disclaimer: jestem autorem tego pakietu), który ma ten, i wiele innych zagadnień wieloletnie PyYAML, naprawiono:

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) 

daje:

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

Jeśli naprawdę trzeba trzymać PyYAML, można zrobić:

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]') 

pozbyć się błędu.


Począwszy od wersji 0.15.16, ruamel.yaml obecnie wysypisk towarzyszącymi płaszczyzny Unicode bez powrotu do \Uxxxxxxxx (regulowane w nowym API poprzez .unicode_supplementary, w zależności od allow_unicode).

3

Wydaje się to być błąd w pyyaml, obejście tego problemu jest użycie ich sekwencji ucieczki:

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

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

Aghhhh genialny! Dlaczego o tym nie pomyślałeś !? Dziękuję Ci! –