Pspell
Pspell asi nepatří k nejpoužívanějším rozšířením PHP, já jsem ho ale už dvakrát použil k poměrně zajímavým úkolům. Pspell je rozšíření, které v PHP umožňuje používat kontrolu pravopisu, při instalaci odpovídajícího slovníku i pro češtinu.
Skoro mě až překvapilo, jak jednoduše jde v PHP napsat aplikace pro asistované přidání háčků a čárek do textu bez diakritiky. Pro vytvoření celé aplikace se hodí i dobrá znalost JavaScriptu a pokud možno také statistických metod, z pohledu PHP je ale asi nejzajímavější funkce, která vrátí všechny možné varianty slova bez diakritiky:
<?php define("ISO_8859_2", "áčďéěíňóřšťúůýžÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ"); define("US_ASCII", "acdeeinorstuuyzACDEEINORSTUUYZ"); /** Vrácení variant slov s diakritikou nalezených ve slovníku * @param string začešťované slovo obvykle bez diakritiky (stávající diakritika se ponechá) * @return array správné varianty slova - array("var1", ...) */ function zacesti_slovo($slovo) { static $pspell; if (!isset($pspell)) { pspell_config_create("cs"); $pspell = pspell_new("cs"); } static $pismena; // array("a" => "á", "e" => "éě", ...) if (!isset($pismena)) { for ($i=0; $i < strlen(US_ASCII); $i++) { $pismena[substr(US_ASCII, $i, 1)] .= substr(ISO_8859_2, $i, 1); } } $moznosti = array(""); for ($i=0; $i < strlen($slovo); $i++) { foreach ($moznosti as $key => $val) { $moznosti[$key] .= $slovo[$i]; for ($j=0; $j < strlen($pismena[$slovo[$i]]); $j++) { $moznosti[] = $val . $pismena[$slovo[$i]][$j]; } } } foreach ($moznosti as $key => $val) { if (!pspell_check($pspell, $val)) { unset($moznosti[$key]); } } return $moznosti; } ?>
Elegantní mi přijde obzvláště část, která naplní pole $moznosti
všemi možnými variantami slova. Je to sice poměrně hutné čtivo, ale svůj účel splní myslím šikovně. Připomínám, že konstrukce $slovo[$i]
se používá pro získání $i
-tého znaku řetězce $slovo
a odpovídá tedy zápisu substr($slovo, $i, 1)
.
V druhém případě jsem rozšíření Pspell použil pro kontrolu pravopisu na stránkách, tam ale kromě rozřezání textu na slova a použití správného jazyka v závislosti na hodnotách atributů lang nic až tak zajímavého není.
Diskuse
spaze:
Wow, zajimava vec :) Ale chtel bych poprosit o jednu vec. Nemam rad postupy copy/paste, snazim se pouzivanej kod nejdriv pochopit -- a to tvoje husty cteni je opravdu husty, slo by k tomu priste napsat nejakej komentar ve stylu:
<?php
// V tomto cyklu vytvarime maly zombiky, zasadime je do pole.
// V tom poli je pak budeme zalevat, stanou se z nich vetsi zombici,
// az z nich bude cela armada, ukoncime produkci, jsme tak pripraveni k boji.
for ($i=0; $i < strlen($slovo); $i++) {
foreach ($moznosti as $key => $val) {
$moznosti[$key] .= $slovo{$i};
for ($j=0; $j < strlen($pismena[$slovo{$i}]); $j++) {
$moznosti[] = $val . $pismena[$slovo{$i}]{$j};
}
}
}
?>
Rozumim, ze komentar by mohl delsi nez samotnej kod (a ze "A TRUE Klingon warrior does not comment his code!"), ale prece jen by to hodne pomohlo k rychlymu ziskani prehledu o tom, co ten kod vlastne dela. Dik :)

Leo:
A k tomu bych se pridat, komentaru pro nas natvrdlejsi neni nikdy dost, diky predem, Leo
Jakub Vrána
:
Pokusím se, ať to k něčemu je. Ono se PHP dá číst líp než třeba svahilština, ale pro spoustu lidí pořád hůř než čeština :-).
Ten kód postupuje po jednotlivých písmenech proměnné $slovo, ke všem existujícím prvkům v poli $moznosti přidá aktuální písmeno (bez diakritiky) a následně do pole přidá možnosti vzniklé doplněním diakritiky. Takže z řetězce "ale" vznikne postupně:
array("a", "á")
array("al", "ál")
array("ale", "ále", "alé", "alě", "álé", "álě")


spaze:
.. a pokud jsem to pochopoval spravne, tak se potom kazdej ten prvek vzniklyho pole prozene pspell_check()-em, jestli takovy slovo existuje v danym jazyce -- takze treba slova jako "álě" se unset()nou. Hmm, chytry vyuziti spellcheckeru ;)
___
ne, ze by PHP bylo pro me svahilstinou, ale mozna i ty sam za pul roku bys svuj komentar ocenil ;) (bez urazky, samo)

peta:
Souhlasím s tebou, kód příkladu jsem si prošel a postupně jsem si ho přepsal do srozumitelnější podoby. Sice je o nějakých deset řádků delší, možná je i o pár setinek pomalejší, ale alespoň bude dobře čitelný i po delší době...Orrorin:
až na tu exponenciální složitost dobrý
Jakub Vrána
:
Dobrá poznámka. Složitost je exponenciální vzhledem k délce slova, která je omezená, takže je to i tak schopné provozu. Složitost by se dala významně srazit, pokud bychom měli přímý přístup ke všem slovům s diakritikou. Pokud máme k dispozici pouze funkci pspell_check(), tak to vylepšit podle mě nepůjde.


Diskuse je zrušena z důvodu spamu.

