Autor Zpráva
Tomášeek
Profil
Poprosím nějakého hodného admmmina, aby příspěvek upravil, z nějakého důvodu se nějak divně naklonoval do sebe vícekrát. Obsahuje 2 bloky kódu a pod nimi odstaveček s poděkováním. Dále jde o duplicitu, kterou nejsem schopen odstranit ani editací. Děkuji.
Moderátor juriad: Opraveno

Ahoj,

chci se zeptat na rozdíly (v rychlost, platnosti znaků, které projdou, jinými) mezi dvěma způsoby - definicí znaků a jejich nahrazením, případně regulárním výrazem. Konkrétně se jedná o komponentu CMS, které používám a které v současné verzi používá regulár, zatímco ve starší verzi používal pole pro nahrazní znaků.

Obě možnosti přikládám. Důvod, proč to řeším, je ten, že ve staré verzi převáděl diakritiku na nediakritické znaky (Ř > R), v nové verzi diakritiku nechává, což se mi v URL, pro které je tato funkce určena, nelíbí (a i mi to přijde nepraktické).

Původní kód:
function create_slug($alias, $tolower = true, $withslash = false) {
    $toreplace  = array(
                "Ä","ä","Æ","æ","Ǽ","ǽ","Å","å","Ǻ","ǻ","À","Á","Â","Ã","à","á","â","ã","Ā","ā","Ă","ă","Ą","ą","Ǎ","ǎ","Ạ","Ạ","ạ","Ả","ả","Ấ","ấ","Ầ","ầ","Ẩ","ẩ","Ẫ","ẫ","Ậ","ậ","Ắ","ắ","Ằ","ằ","Ẳ","ẳ","Ẵ","ẵ","Ặ","ặ",
                "Ç","ç","Ć","ć","Ĉ","ĉ","Ċ","ċ","Č","č",
                "Ð","ð","Ď","ď","Đ","đ",
                "È","É","Ê","Ë","è","é","ê","ë","Ē","ē","Ĕ","ĕ","Ė","ė","Ę","ę","Ě","ě","Ẹ","ẹ","Ẻ","ẻ","Ẽ","Ế","ế","Ề","ề","Ể","ể","ễ","Ệ","ệ","Ə","ə",
                "ſ","ſ",
                "Ĝ","ĝ","Ğ","ğ","Ġ","ġ","Ģ","ģ",
                "Ĥ","ĥ","Ħ","ħ",
                "Ì","Í","Î","Ï","ì","í","î","ï","Ĩ","ĩ","Ī","ī","Ĭ","ĭ","Į","į","İ","ı","Ǐ","ǐ","Ỉ","ỉ","Ị","ị",
                "IJ","ij",
                "fi","fl",
                "Ĵ","ĵ",
                "Ķ","ķ","ĸ",
                "Ĺ","ĺ","Ļ","ļ","Ľ","ľ","Ŀ","ŀ","Ł","ł",
                "Ñ","ñ","Ń","ń","Ņ","Ň","ň","ʼn","Ŋ","ŋ",
                "Ö","ö","Ø","ø","Ǿ","ǿ","Ò","Ó","Ô","Õ","ò","ó","ô","õ","Ō","ō","Ŏ","ŏ","Ő","ő","Ǒ","ǒ","Ọ","ọ","Ỏ","ỏ","Ố","ố","Ồ","ồ","Ổ","ổ","Ỗ","ỗ","Ộ","ộ","Ớ","ớ","Ờ","ờ","Ở","ở","Ỡ","ỡ","Ợ","ợ","Ơ","ơ",
                "Œ","œ",
                "Ŕ","ŕ","Ŗ","ŗ","Ř","ř",
                "Ś","ś","Ŝ","Ş","ş","Š","š",
                "Ţ","ţ","Ť","ť","Ŧ","ŧ",
                "Ü","ü","Ù","Ú","Û","ù","ú","û","Ụ","ụ","Ủ","ủ","Ứ","ứ","Ừ","ừ","Ữ","ữ","Ự","ự","Ũ","ũ","Ū","ū","Ŭ","ŭ","Ů","ů","Ű","ű","Ų","ų","Ǔ","ǔ","ǖ","ǘ","Ǚ","ǚ","Ǜ","ǜ","Ư","ư",
                "Ŵ","ŵ","Ẁ","ẁ","Ẃ","ẃ","Ẅ","ẅ",
                "Ý","ý","ÿ","Ŷ","ŷ","Ÿ","Ỳ","ỳ","Ỵ","ỵ","Ỷ","ỷ","Ỹ","ỹ",
                "Þ","þ","ß",
                "Ź","ź","Ż","ż","Ž","ž",
                "А", "Б", "В", "Г", "Д", "Е", "Ё", "Ж", "З", "И", "Й", "К", "Л", "М", "Н", "О", "П", "Р", "С",
                "Т", "У", "Ф", "Х", "Ц", "Ч", "Ш", "Щ", "Ъ", "Ы", "Ь", "Э", "Ю", "Я",
                "а", "б", "в", "г", "д", "е", "ё", "ж", "з", "и", "й", "к", "л", "м", "н", "о", "п", "р", "с",
                "т", "у", "ф", "х", "ц", "ч", "ш", "щ", "ъ", "ы", "ь", "э", "ю", "я",
    );
    $replacement = array(
                "ae","ae","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a",
                "c","c","c","c","c","c","c","c","c","c",
                "d","d","d","d","d","d",
                "e","e","e","e","e","e","e","e","e","e","e","e","e","e","e","e","e","e","e","e","e","e","e","e","e","e","e","e","e","e","e","e","e","e",
                "f","f",
                "g","g","g","g","g","g","g","g",
                "h","h","h","h",
                "i","i","i","i","i","i","i","i","i","i","i","i","i","i","i","i","i","i","i","i","i","i","i","i",
                "ij","ij",
                "fi","fl",
                "j","j",
                "k","k","k",
                "l","l","l","l","l","l","l","l","l","l",
                "n","n","n","n","n","n","n","n","n","n",
                "oe","oe","o","o","o","o","o","o","o","o","o","o","o","o","o","o","o","o","o","o","o","o","o","o","o","o","o","o","o","o","o","o","o","o","o","o","o","o","o","o","o","o","o","o","o","o","o","o",
                "oe","oe",
                "r","r","r","r","r","r",
                "s","s","s","s","s","s","s",
                "t","t","t","t","t","t",
                "ue","ue","u","u","u","u","u","u","u","u","u","u","u","u","u","u","u","u","u","u","u","u","u","u","u","u","u","u","u","u","u","u","u","u","u","u","u","u","u","u","u","u",
                "w","w","w","w","w","w","w","w",
                "y","y","y","y","y","y","y","y","y","y","y","y","y","y",
                "th","th","ss",
                "z","z","z","z","z","z",
                "a", "b", "v", "g", "d", "e", "e", "zh", "z", "i", "j", "k", "l", "m", "n", "o", "p", "r", "s",
                "t", "u", "f", "h", "ts", "ch", "sh", "sch", "", "y", "", "e", "yu", "ya",
                "a", "b", "v", "g", "d", "e", "e", "zh", "z", "i", "j", "k", "l", "m", "n", "o", "p", "r", "s",
                "t", "u", "f", "h", "ts", "ch", "sh", "sch", "", "y", "", "e", "yu", "ya",
    );

    $alias = str_replace($toreplace, $replacement, $alias);

    if ($tolower !== false) {
        $alias = strtolower($alias);
    }

    $expr = '/[^a-z0-9-_]+/i';
    if ($withslash) {
        $expr = '/[^a-z0-9-_\/]+/i';
    }
    
    $alias = preg_replace($expr,'-',$alias);
    $alias = trim($alias, '-');

    return $alias;
}

Nově tato funkce vypadá takhle, bez definice znaků, které jsou nahrazené regulárem

function create_slug($alias, $tolower = true, $withslash = false {
  if ($tolower !== false) $alias = mb_strtolower($alias);

  // remove invalid chars
  $expr = '/[^\p{L}_\-\.\ \d]/u';
  if ($withslash) $expr = '/[^\p{L}_\.\-\ \d\/]/u';

  $tmp = trim(preg_replace($expr,'',$alias));

  // remove extra dashes and spaces.
  $tmp = str_replace(' ','-',$tmp);
  $tmp = str_replace('---','-',$tmp);
  $tmp = str_replace('--','-',$tmp);

  return trim($tmp);
}

Je z nějakého důvodu druhá varianta s regexpem /[^\p{L}_\-\.\ \d]/u lepší a případně proč? Pokud ano, dá se do ní nějak snadno doroubovat diakritika, aby ji to ignorovalo?
Nahradit novou funkci za starou jde a vypadá to funkčně, s tím by problém nebyl. Spíše mě zajímá, proč se k tomuto tvůrci uchýlili a jestli to má nějaké výhody, které nedokáži rozeznat.


Děkuji.
smitka
Profil
Podle všeho není druhá varianta dělaná aby generovala slug bez diakritiky - pouze odstraňuje speciální znaky.

Klíčové je ^\p{L} - to jsou všechny znaky mimo těch, které jsou v unicode vedené jako Letter - což jsou i všechny znaky s diakritikou.

Asi by to šlo po vyhození speciálních znaků ještě překonvertovat například pomocí iconv:

$tmp = iconv('UTF-8', 'ASCII//TRANSLIT', $tmp);

Druhý způsob má několik výhod - je o něco přehlednější a především počítá s mnohem větší skupinou znaků, ke které by bylo extrémně složité rozšiřovat "slovník" z první varianty.
Tomášeek
Profil
smitka:
Podle všeho není druhá varianta dělaná aby generovala slug bez diakritiky
Ano, to není, to jsem psal. Plus jestli je možné nějak jednoduše diakritiku přidat k odstranění - to píšeš, že snadno nepůjde.

Druhý způsob má několik výhod - je o něco přehlednější
Ano, to je.

a především počítá s mnohem větší skupinou znaků
Ten regulár chápu, že nevyhazuje prakticky nic.

Vzhledem k tomu, že potřebuji tímto systémem generovat slugy pro češtinu, polštinu,němčinu a angličtinu a ten původní výčet znaků mi takto zatím dostačuje a řeší mou potřebu, asi u něj zůstanu. Spíše mi šlo o to, jestli druhý způsob má nějaké extra výhody, krom toho, že toho propustí více (což je v případě URL, na které je tato fce určena, nepraktické, ač funkční - jsem staromilec a diakritika do mých projektů do URL nepatří).
smitka
Profil
Pro běžné použití na prvním způsobu nic špatného nevidím, ale zkus si původní funkcí přeložit třeba sandbox.onlinephpfunctions.com/code/840a8c3b9418cf01adf520a914825eb1781300d4
Tomášeek
Profil
smitka:
Pro běžné použití na prvním způsobu nic špatného nevidím
OK, to jsem potřeboval slyšet. Jsem totiž téhož názoru.

ale zkus si původní funkcí přeložit třeba
Jasně, tam to selže. URL bude v tomto případě chudší než titulek stránky. Ale je to problém reálný (tato je řečnická)? Spíše ne.
smitka
Profil
Tomášeek:
Ale je to problém reálný (tato je řečnická)? Spíše ne.
Souhlas, jen jsem chtěl naznačit možnou motivaci autorů pro použití tříd znaků v unicode. Pro jazyky s opravdu exotickými znaky to může mít smysl.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: