Autor Zpráva
JoK1955
Profil *
Zdravím všechny. Pustil jsem se do předělání webu regionálních Našich novin. Byl vytvořen před více jak 10 lety a tak vypadá jak vypadá. Byl bych rád kdyby mi někdo poradil s následujícím: ve staré tabulce databáze je v poli autor napatláno spoustu jmen bez ladu a skladu. Chtěl bych jim dát řád a pak přenést do nové tabulky.
Ta jména mohou vypadat např:
Alois Novák, alois novák, Alois Novak, _Alois Novák, A. Novák... atp. Chtěl bych aby toto všechno bylo nahrazeno tvarem Alois NOVÁK.
Umím vytáhnou data ze staré tabulky, zkontrolovat a převést na správný tvar podle pole a uložit do nové tab. Znamená to však mít v polích vypsány všechny možné varianty špatných jmen a to mě jímá hrůza. Dalším řešením je export do csv a úprava v tabulkovém procesoru - ještě větší šílenost :-( Napdlo mě použít "nějak" regulární výrazy a odpovídající funkce php... Poradíte někdo pls? JoK
juriad
Profil
Napiš si program, který oddře tu nejhorší práci a pak dokonči ručně.
Nějak si načti všechna data a rozlam každý záznam podle mezer, převeď na malá písmena, zruš diakritiku pomocí ASCII//TRANSLIT, zahoď vše kromě písmen a teček, seřad primárně podle posledního prvku, následně podle zbývajících od prvního (s tečkou budeš zacházet opatrně).
Ke každému záznamu si budeš pamatovat originální variantu a míru správnosti: záznam neobsahující tečku +1 bod, diakrtitika +1 bod, větší počet slov +1 bod, obsahoval divný znak -1 bod - tím určíš, jaká je pravděpodobnost, že záznam je správně.

V seřazeném seznamu seskupíš záznamy, které se příliš neliší a nahradíš je jedním s největší mírou správnosti.
Pokud záznamu A. Novák odpovídá Aleš Novák i Adam Novák, tak ho asi budeš chápat jako samostatný.
Seřazený seznam pak už jen projdeš očima a doupravíš manuálně.
JoK1955
Profil *
Úžasné. V globále vím o čem mluvíš, ale obávám se, že na detailní řešení mé znalosti nestačí... Zvláště ta část s bodováním je mimo mé chápání. Nemáš nějaký odkaz, kde se toto probírá?
Jinak se nad tím zkusím zamyslet a ještě něco vyhledat... cestu teď znám :-) JoK
juriad
Profil
To bodování jsem si zrovna vymyslel, jde jen o způsob, jak vybrat heuristicky nejlepší záznam. Prostě jen série kritérii, podle kterých bys jako člověk našel nejlepšího "Aleše Nováka" mezi všemi "A. Novaky". Nemusíš používat zrovna celá čísla, ale obecně cokoli, co zohlední, jak moc důležité ono kritérium je.
JoK1955
Profil *
juriad:
Tak jsem to skoro vyřešil. Tvůj postup je určitě zajímavý, ale pro mě náročný na vědomosti a vzhledem k jednorázovosti scriptu jsem ho nepoužil (ale zapamatoval :-)
Vytáhl jsem si všechna Jmena PRIJMENI do pole, jako klíč dal prijmeni. Ty považuji za etalony
Pak jsem vzal ostatní záznamy a duhé slovo porovnal s klíči. Pokud záznam souhlasí nahradím hodnotou z pole. Do pomocné tabulky uložím id, starou hodnotu pole a novou hodnotu
Teď per hand projdu pomocnou tabulku, opravím nové záznamy a pak je naleju zpět do původní tabulky podle id.
Koukal jsem na to zběžně a stačí mi to i když to má nedostatky. Například je tam, více Procházků, ale postup přiřadí prvního z pole...
V dotazu na začátku používám REGEXP. Do regulár výrazů moc nevidím a tak mi tam vyjedou i některá jména nejen velkými písmeny, kdybys poznal kde je chyba, byl bych Ti vděčen... psal jsem do sekce Databází, ale dostalo se mi odkazu na stránku s dlouhým pojednáním. Vzhledem k mé znalosti regvýrazů i angličtiny mi to moc nepomohlo. JoK
Přikládám script na ukázku
include_once ('conn.php');
// pripravim reg vyraz
    $rv = "'^[a-zěščřžýáíéúůňA-ZZŠÁĚČŘŽÝÍÉŮŇŤ]+ [A-ZŠÁĚČŘŽÝÍÉŮŇŇŤ]+$'";
// vyberu jen autory s tvarem Jmeno PRIJMENI
    $sql = "SELECT autor FROM n_foto WHERE autor REGEXP $rv GROUP BY autor ORDER BY autor";
    $result = mysql_query($sql);
    $jmena = array();
    while($data = mysql_fetch_array($result)) {
// oddelim prijmeni
        $words = preg_split('/[ ]+/', $data['autor']);
// a dam ho jako kloic do pole, hodnotou pole je cele spravne jmeno a PRIJMENI
        $jmena[mb_strtolower($words[1],"UTF-8")] = trim($data['autor']);
    }
// a mam pole $jmena, kde jsou vsechna spravna
// vyberu zbyvajici jmena
    $sql = "SELECT id, autor FROM n_foto WHERE autor NOT REGEXP $rv ORDER BY autor";
    $result = mysql_query($sql);
    while($data = mysql_fetch_array($result)) {
// oddelim prijmeni
        $words = preg_split('/[ ]+/', $data['autor']);
    if(!empty($words[1])) {
        if(array_key_exists(mb_strtolower($words[1],"UTF-8"), $jmena)) {
//        echo "je tam".$jmena[mb_strtolower($words[1],"UTF-8")]."<br>";
        $mjmeno = $jmena[mb_strtolower($words[1],'UTF-8')];
        $val = $data['id'].", '".$mjmeno."', '".$data["autor"]. "'";
        $sqli = "INSERT INTO temp (id, autor, oldname) VALUES ($val)";
        } else {
        $val = $data['id'].", 'NONAME', '".$data['autor']. "'";
        $sqli = "INSERT INTO temp (id, autor, oldname) VALUES ($val)";
        }
        echo $sqli."<br>";
        mysql_query($sqli);
         echo mysql_errno() . ": " . mysql_error() . "\n";
    }
}
juriad
Profil
Samozřejmě, že jednodušší skripty budou někdy stačit, ale pokud bys měl (sta)tisíce autorů, už byl vopruz je procházet. Proto jsem se snažil navrhnout nejlepší možnou heuristiku, která bude "neomylnější".
Na některé úlohy jsou databáze vhodné (uložení dat a vzájemných relací), na některé ne (řetězcové operace). Proto bych jako první získal všechna data do PHP (pomiňme, že bych použil jiný jazyk (Perl)), kde je dostupných více možných řetězcových operací a v něm prováděl všechny úpravy. Zároveň mi to zajistí, že během několika pokusů o nastavení nejlepších parametrů heuristiky si nepoškodím data v databázi.
JoK1955
Profil *
juriad:
jj rozumím. Já do databáze vytahuji data z pdf, která jdou do tiskárny a závěrečnou úpravu používám sed a grep - úžasné ulehčení práce. Tak jdu projet výsledky. Díky a hezký den. JoK

Vaše odpověď


Prosím používejte diakritiku a interpunkci.

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