Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Transliteracja stringu UTF

21 views
Skip to first unread message

Konrad Kosmowski

unread,
Mar 21, 2009, 7:19:24 PM3/21/09
to
Istnieje jakaś funkcja (czy biblioteka) do transliteracji z polskiego na
podstawowy łaciński? Tzn. zamianę wszystkich wystąpień polskich znaków
diakrytycznych na odpowiedniki z alfabetu łacińskiego (ą -> a, ć -> c ...).
Dla ułatwienia stringi są w UTF. :)

--
+ ' .-. .
, * ) )
http://kosmosik.net/ . . '-' . kK

Przemysław Rachwał

unread,
Mar 21, 2009, 7:32:09 PM3/21/09
to
Konrad Kosmowski wrote:
> Istnieje jakaś funkcja (czy biblioteka) do transliteracji z polskiego na
> podstawowy łaciński? Tzn. zamianę wszystkich wystąpień polskich znaków
> diakrytycznych na odpowiedniki z alfabetu łacińskiego (ą -> a, ć -> c ...).
> Dla ułatwienia stringi są w UTF. :)
>
http://nl3.php.net/manual/en/function.mb-ereg-replace.php

Konrad Kosmowski

unread,
Mar 21, 2009, 7:37:22 PM3/21/09
to

> http://nl3.php.net/manual/en/function.mb-ereg-replace.php

Nie za bardzo wiem jak miałaby wyglądać regułka, w perl jest tr/xyz/zxy/cds, w
PHP nie wiem...?

No bo chyba nie mamy na myśli przelatywania stringu znak po znaku w pętli po
tablicy transliteracji? A może mamy? Jak kosztowne jest takie wywołanie? Bo
może nie ma o co kruszyć kopii...

Przemysław Rachwał

unread,
Mar 21, 2009, 7:51:05 PM3/21/09
to

ostatni wpis na samym dole

[code]
function mb_str_ireplace($co, $naCo, $wCzym)
{
$wCzymM = mb_strtolower($wCzym);
$coM = mb_strtolower($co);
$offset = 0;

while(($poz = mb_strpos($wCzymM, $coM, $offset)) !== false)
{
$offset = $poz + mb_strlen($naCo);
$wCzym = mb_substr($wCzym, 0, $poz). $naCo .mb_substr($wCzym,
$poz+mb_strlen($co));
$wCzymM = mb_strtolower($wCzym);
}

return $wCzym;
}[/code]


po lekturze http://nl3.php.net/manual/en/function.mb-eregi-replace.php

jest przykład funkcji

<?php
function do_translit($st) {
$replacement = array(
"й"=>"i","ц"=>"c","у"=>"u","к"=>"k","е"=>"e","н"=>"n",
"г"=>"g","ш"=>"sh","щ"=>"sh","з"=>"z","х"=>"x","ъ"=>"\'",
"ф"=>"f","ы"=>"i","в"=>"v","а"=>"a","п"=>"p","р"=>"r",
"о"=>"o","л"=>"l","д"=>"d","ж"=>"zh","э"=>"ie","ё"=>"e",
"я"=>"ya","ч"=>"ch","с"=>"c","м"=>"m","и"=>"i","т"=>"t",
"ь"=>"\'","б"=>"b","ю"=>"yu",
"Й"=>"I","Ц"=>"C","У"=>"U","К"=>"K","Е"=>"E","Н"=>"N",
"Г"=>"G","Ш"=>"SH","Щ"=>"SH","З"=>"Z","Х"=>"X","Ъ"=>"\'",
"Ф"=>"F","Ы"=>"I","В"=>"V","А"=>"A","П"=>"P","Р"=>"R",
"О"=>"O","Л"=>"L","Д"=>"D","Ж"=>"ZH","Э"=>"IE","Ё"=>"E",
"Я"=>"YA","Ч"=>"CH","С"=>"C","М"=>"M","И"=>"I","Т"=>"T",
"Ь"=>"\'","Б"=>"B","Ю"=>"YU",
);

foreach($replacement as $i=>$u) {
$st = mb_eregi_replace($i,$u,$st);
}
return $st;
}
?>

Jordan Szubert

unread,
Mar 21, 2009, 7:51:44 PM3/21/09
to
Dnia 22-03-2009 o 00:19:24 Konrad Kosmowski <kon...@kosmosik.net>
napisał(a):

> Istnieje jakaś funkcja (czy biblioteka) do transliteracji z polskiego na
> podstawowy łaciński? Tzn. zamianę wszystkich wystąpień polskich znaków
> diakrytycznych na odpowiedniki z alfabetu łacińskiego (ą -> a, ć -> c
> ...).
> Dla ułatwienia stringi są w UTF. :)
>

hmm... moze http://pl.php.net/manual/pl/function.iconv.php i wyjscie jako
ASCII//TRANSLIT ?

--
http://joru.olewales.ath.cx/

Jordan Szubert

unread,
Mar 21, 2009, 7:56:11 PM3/21/09
to
Dnia 22-03-2009 o 00:51:05 Przemysław Rachwał
<przemysla...@gmail.com> napisał(a):

[...]


> po lekturze http://nl3.php.net/manual/en/function.mb-eregi-replace.php
>
> jest przykład funkcji
>
> <?php
> function do_translit($st) {
> $replacement = array(
> "й"=>"i","ц"=>"c","у"=>"u","к"=>"k","е"=>"e","н"=>"n",

[...]


> "Ь"=>"\'","Б"=>"B","Ю"=>"YU",
> );
>
> foreach($replacement as $i=>$u) {
> $st = mb_eregi_replace($i,$u,$st);
> }
> return $st;
> }
> ?>

po co tu eregi? preg jest AFAIK lepsze, ale i tak IMO niepotrzebne,
wyglada ze strtr spokojnie wystarczy, a powinno byc sporo szybsze...

--
http://joru.olewales.ath.cx/

Konrad Kosmowski

unread,
Mar 21, 2009, 8:04:52 PM3/21/09
to
** Przemysław Rachwał <przemysla...@gmail.com> wrote:

>>>> Istnieje jakaś funkcja (czy biblioteka) do transliteracji z polskiego na
>>>> podstawowy łaciński? Tzn. zamianę wszystkich wystąpień polskich znaków
>>>> diakrytycznych na odpowiedniki z alfabetu łacińskiego (ą -> a, ć -> c
>>>> ...). Dla ułatwienia stringi są w UTF. :)

>>> http://nl3.php.net/manual/en/function.mb-ereg-replace.php

>> Nie za bardzo wiem jak miałaby wyglądać regułka, w perl jest tr/xyz/zxy/cds,
>> w PHP nie wiem...?

>> No bo chyba nie mamy na myśli przelatywania stringu znak po znaku w pętli po
>> tablicy transliteracji? A może mamy? Jak kosztowne jest takie wywołanie? Bo
>> może nie ma o co kruszyć kopii...

> ostatni wpis na samym dole

Sorry nie jestem koderem copy&paste oraz zanim zapytałem na grupie to szukałem
rozwiązania i na to też się natknąłem. Szczerze mówiąc nie wiem *praktycznie*
jak to wpłynie na wydajność bo nie mierzyłem, ale w samej teorii ma moim
zdaniem niepotrzebnie dużą złożoność obliczeniową. W przypadku jednego
wywołania to może nie mieć znaczenia, ale ja będę wywoływał to bardzo dużo razy
i to w kolejce której sprawne opróżnienie jest sprawą krytyczną, a każde
opóźnienie spowalnia całość (no takie mam wymagania, że to musi być PHP).

Ergo weź prześledź co robi ten kod. Jest to bardzo prymitywne podejście do
problemu.

(ciach copy&paste)

Konrad Kosmowski

unread,
Mar 21, 2009, 8:07:25 PM3/21/09
to
** Jordan Szubert <to_jest_pra...@mielonka.servebeer.com> wrote:

> po co tu eregi? preg jest AFAIK lepsze, ale i tak IMO niepotrzebne, wyglada
> ze strtr spokojnie wystarczy, a powinno byc sporo szybsze...

Przeczytaj temat posta (albo może ja o czymś nie wiem).

Konrad Kosmowski

unread,
Mar 21, 2009, 8:11:42 PM3/21/09
to
** Jordan Szubert <to_jest_pra...@mielonka.servebeer.com> wrote:

>> Istnieje jakaś funkcja (czy biblioteka) do transliteracji z polskiego na
>> podstawowy łaciński? Tzn. zamianę wszystkich wystąpień polskich znaków
>> diakrytycznych na odpowiedniki z alfabetu łacińskiego (ą -> a, ć -> c ...).
>> Dla ułatwienia stringi są w UTF. :)

> hmm... moze http://pl.php.net/manual/pl/function.iconv.php i wyjscie jako
> ASCII//TRANSLIT ?

No właśnie nie. Robię tak:

<?php
$in="Założyć gęślą jaźń";
$out=iconv("UTF-8","ASCII//TRANSLIT",$in);
echo $out;
?>

I dostaję "Za?o?y? g??l? ja??".

:\

Konrad Kosmowski

unread,
Mar 21, 2009, 8:13:53 PM3/21/09
to
** Konrad Kosmowski <kon...@kosmosik.net> wrote:

>>> Istnieje jakaś funkcja (czy biblioteka) do transliteracji z polskiego na
>>> podstawowy łaciński? Tzn. zamianę wszystkich wystąpień polskich znaków
>>> diakrytycznych na odpowiedniki z alfabetu łacińskiego (ą -> a, ć -> c
>>> ...). Dla ułatwienia stringi są w UTF. :)

>> hmm... moze http://pl.php.net/manual/pl/function.iconv.php i wyjscie jako
>> ASCII//TRANSLIT ?

> No właśnie nie. Robię tak:

> <?php $in="Założyć gęślą jaźń"; $out=iconv("UTF-8","ASCII//TRANSLIT",$in);
> echo $out; ?>

> I dostaję "Za?o?y? g??l? ja??".

> :\

Aaa no i:

kosmosik$ enca translit.php
Universal transformation format 8 bits; UTF-8

Konrad Kosmowski

unread,
Mar 21, 2009, 8:25:06 PM3/21/09
to
** Konrad Kosmowski <kon...@kosmosik.net> wrote:

> Ergo weź prześledź co robi ten kod. Jest to bardzo prymitywne podejście do
> problemu.

Tzn. może w sumie (my bad) złożoność się nie zmienia natomiast wolałbym takie
przetwarzanie zrzucać "niżej" (do biblioteki napisanej w języku niższego
poziomu) bo to się wydajniej wykonuje.

Exe Very Cute

unread,
Mar 21, 2009, 8:23:10 PM3/21/09
to
Konrad Kosmowski pisze:

> Istnieje jakaś funkcja (czy biblioteka) do transliteracji z polskiego na
> podstawowy łaciński?

A nie może być po prostu:

function foo($s)
{
$data = array(
"\xc4\x85" => "a", "\xc4\x84" => "A", "\xc4\x87" => "c", "\xc4\x86"
=> "C",
"\xc4\x99" => "e", "\xc4\x98" => "E", "\xc5\x82" => "l", "\xc5\x81"
=> "L",
"\xc3\xb3" => "o", "\xc3\x93" => "O", "\xc5\x9b" => "s", "\xc5\x9a"
=> "S",
"\xc5\xbc" => "z", "\xc5\xbb" => "Z", "\xc5\xba" => "z", "\xc5\xb9"
=> "Z",
"\xc5\x84" => "n", "\xc5\x83" => "N");
return strtr($s, $data);
}

? Jest szybkie (jak na PHP ;]), i u mnie się to sprawdza od dłuższego
czasu...

Pozdr
Exe Very Cute

Konrad Kosmowski

unread,
Mar 21, 2009, 8:38:14 PM3/21/09
to

O. Dzięki. ;)

Piotr Keplicz

unread,
Mar 22, 2009, 6:03:40 AM3/22/09
to
Konrad Kosmowski:

> <?php
> $in="Założyć gęślą jaźń";
> $out=iconv("UTF-8","ASCII//TRANSLIT",$in);
> echo $out;
> ?>
>
> I dostaję "Za?o?y? g??l? ja??".

To raczej wygląda na problem z localesami, bo to powinno działać (i SOA#1).

.pk.

Jordan Szubert

unread,
Mar 22, 2009, 7:27:13 AM3/22/09
to
Dnia 22-03-2009 o 01:11:42 Konrad Kosmowski <kon...@kosmosik.net>
napisał(a):

a locale ustawiles?

--
http://joru.olewales.ath.cx/

Jordan Szubert

unread,
Mar 22, 2009, 7:29:56 AM3/22/09
to
Dnia 22-03-2009 o 01:07:25 Konrad Kosmowski <kon...@kosmosik.net>
napisał(a):

> ** Jordan Szubert <to_jest_pra...@mielonka.servebeer.com> wrote:
>
>> po co tu eregi? preg jest AFAIK lepsze, ale i tak IMO niepotrzebne,
>> wyglada
>> ze strtr spokojnie wystarczy, a powinno byc sporo szybsze...
>
> Przeczytaj temat posta (albo może ja o czymś nie wiem).

nadal nie widze, czemu cos takiego ma nie dzialac...
strtr($in, array(


"\xc4\x85" => "a", "\xc4\x84" => "A", "\xc4\x87" => "c", "\xc4\x86" =>
"C",
"\xc4\x99" => "e", "\xc4\x98" => "E", "\xc5\x82" => "l", "\xc5\x81" =>
"L",
"\xc3\xb3" => "o", "\xc3\x93" => "O", "\xc5\x9b" => "s", "\xc5\x9a" =>
"S",
"\xc5\xbc" => "z", "\xc5\xbb" => "Z", "\xc5\xba" => "z", "\xc5\xb9" =>
"Z",

"\xc5\x84" => "n", "\xc5\x83" => "N" ));

--
http://joru.olewales.ath.cx/

porneL

unread,
Mar 22, 2009, 9:29:49 AM3/22/09
to
On Sun, 22 Mar 2009 00:07:25 -0000, Konrad Kosmowski <kon...@kosmosik.net> wrote:

>> po co tu eregi? preg jest AFAIK lepsze, ale i tak IMO niepotrzebne,
>> wyglada ze strtr spokojnie wystarczy, a powinno byc sporo szybsze...
>
> Przeczytaj temat posta (albo może ja o czymś nie wiem).

Ano najwyraźniej nie wiesz, że UTF-8 jest zaprojektowany tak, żeby bajtowy find'n'replace działał prawidłowo (ciąg bajtów reprezentujący codepoint nigdy nie jest podciągiem innego codepointu).

Poza tym jak już wyrażenia regularne, to nie przestarzałe (mb_)ereg, tylko preg z flagą u.

--
http://pornel.net
this.author = new Geek("porneL");

Konrad Kosmowski

unread,
Mar 22, 2009, 12:10:41 PM3/22/09
to
** Jordan Szubert <to_jest_pra...@mielonka.servebeer.com> wrote:

>>> po co tu eregi? preg jest AFAIK lepsze, ale i tak IMO niepotrzebne,
>>> wyglada ze strtr spokojnie wystarczy, a powinno byc sporo szybsze...

>> Przeczytaj temat posta (albo może ja o czymś nie wiem).

> nadal nie widze, czemu cos takiego ma nie dzialac...
> strtr($in, array(
> "\xc4\x85" => "a", "\xc4\x84" => "A", "\xc4\x87" => "c", "\xc4\x86" =>
> "C",
> "\xc4\x99" => "e", "\xc4\x98" => "E", "\xc5\x82" => "l", "\xc5\x81" =>
> "L",
> "\xc3\xb3" => "o", "\xc3\x93" => "O", "\xc5\x9b" => "s", "\xc5\x9a" =>
> "S",
> "\xc5\xbc" => "z", "\xc5\xbb" => "Z", "\xc5\xba" => "z", "\xc5\xb9" =>
> "Z",
> "\xc5\x84" => "n", "\xc5\x83" => "N" ));

Powyższe działa ale nie jest to do końca to o czym pisałem, pytałem jak
zamienić ciąg "ą" na "a", powyższe zamienia ciąg "\xc4\x85" na "a". Jest pewna
subtelna różnica.

Konrad Kosmowski

unread,
Mar 22, 2009, 12:09:11 PM3/22/09
to
** Jordan Szubert <to_jest_pra...@mielonka.servebeer.com> wrote:

>>>> Istnieje jakaś funkcja (czy biblioteka) do transliteracji z polskiego na
>>>> podstawowy łaciński? Tzn. zamianę wszystkich wystąpień polskich znaków
>>>> diakrytycznych na odpowiedniki z alfabetu łacińskiego (ą -> a, ć -> c
>>>> ...). Dla ułatwienia stringi są w UTF. :)

>>> hmm... moze http://pl.php.net/manual/pl/function.iconv.php i wyjscie jako
>>> ASCII//TRANSLIT ?

>> No właśnie nie. Robię tak:

>> <?php $in="Założyć gęślą jaźń"; $out=iconv("UTF-8","ASCII//TRANSLIT",$in);
>> echo $out; ?>

>> I dostaję "Za?o?y? g??l? ja??".

> a locale ustawiles?

Dodałem do powyższego kodu "setlocale(LC_ALL, 'pl_PL');", w php.ini ustawiłem
na UTF-8 zgodnie z tym:

http://pl.php.net/manual/pl/iconv.configuration.php

I nadal powyższe nie działa.

W ilu jeszcze miejscach zmienia się locale w PHP? PHP dystrybucyjne z RHEL 5.3.

Konrad Kosmowski

unread,
Mar 22, 2009, 12:15:04 PM3/22/09
to
** porneL <niu...@pornel.net> wrote:

>>> po co tu eregi? preg jest AFAIK lepsze, ale i tak IMO niepotrzebne,
>>> wyglada ze strtr spokojnie wystarczy, a powinno byc sporo szybsze...

>> Przeczytaj temat posta (albo może ja o czymś nie wiem).

> Ano najwyraźniej nie wiesz, że UTF-8 jest zaprojektowany tak, żeby bajtowy
> find'n'replace działał prawidłowo (ciąg bajtów reprezentujący codepoint nigdy
> nie jest podciągiem innego codepointu).

> Poza tym jak już wyrażenia regularne, to nie przestarzałe (mb_)ereg, tylko
> preg z flagą u.

Np. tak:
http://pl.php.net/manual/pl/function.preg-replace.php#86394

Co jest wydajniejsze to czy strtr?

Jordan Szubert

unread,
Mar 22, 2009, 1:10:39 PM3/22/09
to
Dnia 22-03-2009 o 17:10:41 Konrad Kosmowski <kon...@kosmosik.net>
napisał(a):

no powyzsze zamienia "ą" zakodowane w utf-8 na "a"... zapis "ą" ma rozne
znaczenie zalaznie od kodowania pliku, "\xc4\x85" zawsze jest "ą" w
utf-8...
innych roznic nie widze...

--
http://joru.olewales.ath.cx/

Jordan Szubert

unread,
Mar 22, 2009, 1:37:04 PM3/22/09
to
Dnia 22-03-2009 o 17:15:04 Konrad Kosmowski <kon...@kosmosik.net>
napisał(a):

klasyczna odpowiedz brzmi "Zmierz", ale nie sadze by ogole regexpy byly
szybsze niz dedykowane do tego strtr...

--
http://joru.olewales.ath.cx/

porneL

unread,
Mar 22, 2009, 4:34:55 PM3/22/09
to
On Sun, 22 Mar 2009 16:09:11 -0000, Konrad Kosmowski <kon...@kosmosik.net> wrote:

>> a locale ustawiles?
>
> Dodałem do powyższego kodu "setlocale(LC_ALL, 'pl_PL');", w php.ini
> ustawiłem na UTF-8 zgodnie z tym:
>
> http://pl.php.net/manual/pl/iconv.configuration.php
>
> I nadal powyższe nie działa.
>
> W ilu jeszcze miejscach zmienia się locale w PHP? PHP dystrybucyjne z
> RHEL 5.3.

A masz takie locale w systemie? Spróbuj też "pl_PL.utf8"

Jak nie masz, to zobacz localedef albo locale-gen.

porneL

unread,
Mar 22, 2009, 4:36:48 PM3/22/09
to
On Sun, 22 Mar 2009 17:10:39 -0000, Jordan Szubert <to_jest_pra...@mielonka.servebeer.com> wrote:

> no powyzsze zamienia "ą" zakodowane w utf-8 na "a"... zapis "ą" ma rozne
> znaczenie zalaznie od kodowania pliku, "\xc4\x85" zawsze jest "ą" w
> utf-8...
> innych roznic nie widze...

Tak na marginesie, "ą" można też zapisać w UTF-8 jako "a\xCC\xA8".

Konrad Kosmowski

unread,
Mar 22, 2009, 7:34:06 PM3/22/09
to
** Jordan Szubert <to_jest_pra...@mielonka.servebeer.com> wrote:

>> Co jest wydajniejsze to czy strtr?

> klasyczna odpowiedz brzmi "Zmierz", ale nie sadze by ogole regexpy byly
> szybsze niz dedykowane do tego strtr...

Klasycznie wykonałem lazy web bo może ktoś już mierzył. :)

0 new messages