» »

Unicode decode

Unicode decode

poweroff ::

V PSQL bazi imam seznam vseh zakonov oz. predpisov sprejetih v Sloveniji (19712 zapisov). Te podatke bi rad izvozil v tabelo v obliki:
naslov_zakona presledek besedilo_zakona

To naredim nekako takole:
\COPY (select replace(naslov_zakona, ' ', '_'), regexp_replace(vsebina_zakona, E'[\\n\\r\\u2028]+', ' ', 'g' ) from zakonodaja_zakoni, zakonodaja_besedila where (zakonodaja_zakoni.sop = zakonodaja_besedila.sop) and (id ~* 'zak')) to 'besedila_zakonov_ontogen.txt' with csv header delimiter ' ' encoding 'WIN1250';


- naslov_zakona spremenim tako, da so namesto presledkov podčrtaji;
- sledi presledek, nato pa iz vsebina_zakona odstranim vse newline in UTF-8 znak u2028;
- zadevo zapišem v TXT datoteko besedila_zakonov_ontogen.txt v CP-1250 kodnem zapisu.

Problem, dobim tale error:
ERROR:  character with byte sequence 0xe2 0x80 0x91 in encoding "UTF8" has no equivalent in encoding "WIN1250"


No, zadevo sem potem zapisal v navadno TXT datoteko v UTF-8 formatu in le-to skušal pretvoriti iz UTF-8 v nek normalen format. Uporabil sem Unidecode.

Zadevo v bashu poženem takole:
unidecode besedila_zakonov_ontogen.txt > besedila_zakonov_ontogen_win.txt


Ven pade prazna datoteka (besedila_zakonov_ontogen_win.txt), v ukazni vrstici pa se izpiše tole:
Pobit


Any idea kaj je narobe?
sudo poweroff

poweroff ::

Recode tudi ne dela. Če rečem:
recode UTF8..CP1250 besedila_zakonov_ontogen.txt


Dobim:
recode: besedila_zakonov_ontogen.txt neuspešno: Neveljaven vhod v koraku ,UTF-8..CP1250`


Issto je iconv:
iconv -f utf-8 -t cp1250 besedila_zakonov_ontogen.txt > besedila_zakonov_ontogen_win.txt


iconv: illegal input sequence at position 1263633
sudo poweroff

Zgodovina sprememb…

  • spremenilo: poweroff ()

Randomness ::

Nič ne delaš narobe. V datoteki besedila_zakonov_ontogen.txt imaš očitno znak, ki ga ni mogoče predstaviti v cp1250. Ta znak je '-', ki v kakšni pisavi mogoče na pogled zgleda enako kot znak '-', a gre za popolnoma drug "unicode code point".

P.S. Zakaj ne obdržiš datoteke kar v utf-8, ki je v današnjem času kar se mene tiče edini smiseln txt format?

Zgodovina sprememb…

poweroff ::

Zato, ker bi za nadaljnjo analizo želel uporabiti nek Wintendo-only software, ki ne podpira UTF-8...

Kako pa ta "-" odstranim ročno s PSQL?
sudo poweroff

Randomness ::

sed 's/\xe2\x80\x91/-/g' besedila_zakonov_ontogen.txt | iconv -f utf-8 -t cp1250 > besedila_zakonov_ontogen_win.txt

Spura ::

Ponavadi lahko ce zelis nadomestis znake, ki se jih ne da predstavit z nekim drugim znakom. Vsaj v Javi je tako. Sicer je pa taka stvar par vstic v javi.

avian2 ::

Matthai, kar se tiče Unidecode se mi zdi, da narobe razumeš njegov namen. Unidecode nadomesti vse znake, ki jih ni mogoče predstaviti v 7-bitnem ASCII naboru. Pri tem uporabi znake, ki so jim najbolj podobni. V praksi to pomeni, da bo pri slovenskem besedilu č, ž, š zamenjal za c, z, s. Namen Unidecode ni pretvarjanje med kodnimi nabori temveč na primer izdelava kakih identifikatorjev, ki ne podpirajo polnega Unicode nabora znakov.

Mimogrede, izpis "Pobit" in prazno datoteko dobiš zato, ker je vhodna datoteka prevelika, da bi se v celoti shranila v pomnilnik. "unidecode" orodje za ukazno vrstico namreč pred obdelavo prebere celo datoteko (Python knjižnica, ki jo uporablja, sicer nima te omejitve).

Za tvoj problem bi ti predlagal "iconv" z "//translit" opcijo. Tako ti bo "iconv" avtomatsko nadomestil tisti nerodni pomišljaj (in ostale take primere) s takim, ki je v "cp1250" naboru.

iconv -f utf-8 -t cp1250//translit besedila_zakonov_ontogen.txt > besedila_zakonov_ontogen_win.txt

MrStein ::

Zakaj pa ne bi ta znak nadomestil že v SQL, če si tam že poskrbel za UTF-8 znak u2028 ?
Recimo z minusom.

Sicer potem moraš enako narediti za vse nove morebitne "nerodne" zanke, ki bi se pojavili. Bi pa vsaj potem vedel, kaj je bilo in s čim si nadomestil.
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!

poweroff ::

Ja, saj to bi najraje. A obstaja kakšna funkcija oz. translacijska tabela?
sudo poweroff

MrStein ::

Za kaj?
Da bi znake brez CP1250 kode spremenil v nek veljaven podoben znak?
Izbrisal?
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!

Zgodovina sprememb…

  • spremenil: MrStein ()

poweroff ::

Recimo. Eno ali drugo. Izbris je še najbolj enostaven. In v resnici mi ne dela večjih težav, ker text mining orodje analizira druge zadeve.
sudo poweroff

MrStein ::

Tole za iconv?
  -c     When this option is given, characters that cannot be converted are silently discarded, instead of leading to a conversion error.


Ali pa tole:

iconv -f utf8 -t cp1250//IGNORE 

Šumnike in vse drugo, kar ne gre v cp1250 izpusti iz outputa.
(oziroma šumniki bi naj ostali, v hitrem preizkusu pri meni nekaj zmešalo, ampak načeloma deluje)
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!

Zgodovina sprememb…

  • spremenil: MrStein ()

Randomness ::

Če želiš dotični znak nadomestiti s presledkom, ga samo dodaj v svoj regexp_replace:
regexp_replace(vsebina_zakona, E'[\\n\\r\\u2028\\u2011]+', ' ', 'g' )
Če ga želiš nadomestiti s kakim drugim znakom (npr. '-'), uporabi gnezden regexp_replace:
regexp_replace(regexp_replace(vsebina_zakona, E'[\\n\\r\\u2028]+', ' ', 'g'), E'[\\u2011], '-', 'g')


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

[php] encoding niza

Oddelek: Izdelava spletišč
173790 (1705) BivšiUser2
»

[C++] charset-a

Oddelek: Programiranje
7897 (754) SasoS

python pomoč

Oddelek: Programiranje
393403 (2324) Mavrik
»

[PHP] charter set windows-1250

Oddelek: Programiranje
282813 (2813) Blisk
»

MySQL in czs

Oddelek: Izdelava spletišč
423601 (2691) krho

Več podobnih tem