[ Miroslav Ćurčić @ 16.04.2009. 21:55 ] @
Imao sam problem pri konvertovanju (s preg_replace) teksta koji ima html entitete unutar UTF8 stringa.

Primer:
Code:
preg_replace('/&#(\d+);/e', "chr(\\1)", 'Obućar - šđčćž');

Paterni su preuzeti sa (mislim) wwwphpnet/preg_replace i dobro radi u nekim drugim slučajevima.
Izgleda da je ovde problem to što preg_replace zamenjuje entitet jednim bajtom (funkcija chr) u ovom slučaju 007 (što je overflow od 263), a meni treba dvobajtni ("ć" = 196,135).

Na kraju sam napravio transalaciju svih 8 slova preko strtr funkcije, al to nije univerzalno rešenje, šta ako se pojavi još neki egzotični karakter?

Dakle, kako izvesti translaciju entiteta (u numeričkom obliku) unutar UTF8 stringa?
Ne mora uopšte sa regex, bitno je da radi,
a opet ne bih išao sa nekom komplikovanom analizom (tipa: petlja koja traži "&#" pa čitaj do ";" pa to konvertuj pa zameni) zbog brzine rada.
[ Tudfa @ 17.04.2009. 00:11 ] @
Pozdrav,

pa ako mislimo na isto možda ovo može da pripomogne:

Code:

var_dump('Obućar');
var_dump(html_entity_decode('Obućar',null,'UTF-8'));
var_dump(preg_replace('/&#(\d+);/e', "chr(\\1)", 'Obućar'));


Ako je stranica sačuvana kao UTF-8 sa html_entity_decode dobije se string od sedam karaktera od kojih 2 odlaze na ć,
a ne 6 kao sa preg_replace-om. Ovo ne važi ako se ne koristi argument 'UTF-8'(dobije se 'Obućar' sa var_dump) .
[ Miroslav Ćurčić @ 17.04.2009. 01:12 ] @
Hvala Vlado, ali...

Warning: cannot yet handle MBCS in html_entity_decode()!

Izvini, promaklo mi je da napomenem da mi treba za jedan antički server gde se vrti PHP4.
Probao sam ovo ranije, kao najlogičnije.
[ Miroslav Ćurčić @ 17.04.2009. 01:25 ] @
Ha, rešio,
našao sam negde funkciju koja konvertuje taj unicode broj u UTF8 par bajtova:
Code:

function unichr($c) {
    if ($c <= 0x7F) return chr($c);
     else if ($c <= 0x7FF) return chr(0xC0 | $c >> 6).chr(0x80 | $c & 0x3F);
     else if ($c <= 0xFFFF) return chr(0xE0 | $c >> 12).chr(0x80 | $c >> 6 & 0x3F).chr(0x80 | $c & 0x3F);
     else if ($c <= 0x10FFFF) return chr(0xF0 | $c >> 18).chr(0x80 | $c >> 12 & 0x3F).chr(0x80 | $c >> 6 & 0x3F).chr(0x80 | $c & 0x3F);
     else return false;
    }
}

i onda u paternu umesto "chr(\\1)" stavio "unichr(\\1)" i proradilo.