Van egy log fájlom, amit perlben fel kellene olvasnom. A logot készítő program nagyon ügyel rá, hogy csak latin1 karakterek kerüljenek a logba, ezért mindent elkódol ... majdnem mindent.
Néha azonban bekerül egy-egy utf-8 karakter is a logba, amit innentől nem tudok megfelelően kezelni.
Ezek az utf-8 karakterek mindig valamilyen hibából fakadnak, így elég lenne, ha ezeket le tudnám nyelni, vagy át tudnám ugrani. Az ilyen adatok csonkolása, sérülése nem lenne gond.
Célom, hogy csak latin1 karaktereket olvassak ki a fájlból.
Hiába nyitom meg azonban "< :encoding(Latin1)" módban a fájlt, továbbra is utf-8 karakterként kerül beolvasásra a sérült adat.
Van valakinek valamilyen ötlete?
- 809 megtekintés
Hozzászólások
Először megpróbálnám elhárítani az illegális utf-8 forrást.
A logot készítő program nagyon ügyel rá, hogy csak latin1 karakterek kerüljenek a logba, ezért mindent elkódol ...
Vajon regény is van a logban? ;)
A legkönnyebb út, ha az utf-8 egyértelmű, egy C konverter. A másik pedig az iconv, amivel egyértelműve kell alakítani a karaktereket. Mindkét szűrőt a beolvasás elé lehet kötni.
- A hozzászóláshoz be kell jelentkezni
A program egy exim, és fél év óta először írt a logba olyan nem latin1 karaktereket, amiket fel kellene dolgoznom. Mivel ezek egy e-mail cím elején találhatóak, gyanítom, hogy eleve egy hibásan kódolt címmel akartak levelet küldeni. Az exim meg úgy tűnik, erre nem készült fel, így ezt nem kódolta el.
Lehet, hogy az utf-8 nem egyértelmű. Lehet, hogy csak valamilyen téves bináris adat, amit semmiképp nem lehet latin1-nek értelmezni.
iconv-val prbóbáltam konvertálni a teljes logfájlt, de megszakadt a konverzió karakterkódolási probléma miatt. Úgy látszik, a logban más helyeken is megjelennek bináris adatok, csak épp olyan részeken, amiket nekem nem kell feldolgoznom.
Emiatt maradnék annál, hogy a logfájlt nem bántom, és csak a beolvasott sort kezelném valamilyen konverzióval, hogy kidobáljam belőle a fránya karaktereket, vagy eleve már csak latin1-nek olvasnám be.
- A hozzászóláshoz be kell jelentkezni
Mi lenne, ha kidobnad azokat a karaktereket a stringbol, amelyeknek az erteke szerinted nem megfelelo? Gondolom az ISO8859-1 wikipedia oldalon szereplo "undefined" tipusu karakterektol akarsz megszabadulni.
---
Apple iMac 27"
áéíóöőúüű
- A hozzászóláshoz be kell jelentkezni
Az pont jó lenne. Ehhez keresek valami frappáns perl műveletet vagy modult.
- A hozzászóláshoz be kell jelentkezni
Nem ismerem a nyelvet, de ahogy latom for meg ord van itt is es mar kesz is van egy mukodo megoldas, amivel lehet tesztelni az elmeletet.
---
Apple iMac 27"
áéíóöőúüű
- A hozzászóláshoz be kell jelentkezni
Mivel sok sort kell végigolvasni, és így is elég sokáig tart, a karakterenkénti egyedi elemzésnél remélem, lesz jobb megoldás. Azt is mellőzném, hogy egy reguláris mintában felsoroljam az összes elfogadható karaktert, bár jobb híján ez lesz.
- A hozzászóláshoz be kell jelentkezni
Lehet, hogy az utf-8 nem egyértelmű. Lehet, hogy csak valamilyen téves bináris adat, amit semmiképp nem lehet latin1-nek értelmezni.
Nem értem. A latin1 egy 8-bites karakterkódolás, ahol a 0..255 tartományban van 256 db karakter, mindegyikhez egy egybájtos kód tartozik. Hogy lehet bármi egy fájlban, amit nem lehet latin1-nek értelmezni???
- A hozzászóláshoz be kell jelentkezni
Ez teljesen más helyzet!
A mail headerben (címben) a kódolások és a hibák száma együttvéve meghaladja a végtelent. ;) Érdekes módon szinte minden levelezőprogramban többé-kevésbé képesek voltak megoldani az elégséges megfejtést.
A karakterenkénti feldolgozás egyáltalán nem lassú. (Mint alant írod. Persze nem js-ben kell írni. ;))
Ha
- eldobható az illegális karaktertől a sor, akkor az első ilyet és a sorvéget kell csak megkeresni.
- egyéb hibára gyanakszol, akkor is működhet az algoritmus. (Kérdés, mi rondít oda?)
- ha többféle érvényes kódolás csúszik be, akkor
-- ki kell emelni a címet és
-- a megfejtéshez mail header parsert kell bevetni.
Jó buli!
- A hozzászóláshoz be kell jelentkezni
Ritkán használom, de emlékeim szerint az iconv azt várja, hogy ha egy input fájlt utf-8-ról bármi másra akarsz kódolni, akkor a teljes input utf-8 kódolású, nem csak néhány karaktere. Viszont ha csak néhány karakter utf-8-as, akkor lehet benne bármennyi, utf-8-ban érvénytelen karakter. Így aztán nem csoda, hogy kódolási hibával leáll.
- A hozzászóláshoz be kell jelentkezni
https://www.perlmonks.org/?displaytype=print;node_id=619797
ez alapján ezt a formát javaslom:
$str =~ s/[^!-~\s]//g;
(csak azért ismétlem meg, hogy ne csak link szerepeljen itt)
több működő megoldás van ott.
- A hozzászóláshoz be kell jelentkezni
Erre egyébként van egy modul "It's better than nothing!" alapon: elég ügyes.
use Text::Unidecode qw(unidecode);
$bigyo="Шрек";
$ize=unidecode ($bigyo);
$ize=~ tr/\"\^\~\#\/\,\\\_//d; #gyakorlati tapasztalatból
print "\n$ize\n";
Kiirja, hogy Shrek.
Szerk.: Egyébként jobban érzékelteti a modul a működést ezzel a példával: "çŤрẮχŐőíé" -> "cTpAKhOoie"
- A hozzászóláshoz be kell jelentkezni