Fonetica nel pattern matching con php #2: ridondanza e distanza di Levenshtein

Tempo fa vi ho parlato delle funzioni soundex e metaphone per utilzzare una verifica vocale nel matching tra stringhe di testo. Personalmente dopo alcuni test avevo riscontrato una buona affidabilità di soundex, sono però poi stato smentito, mi è capitato il caso:

via ennio quirino visconti

via m. carucci

soundex mi forniva lo stesso hash mentre sono palesemente differenti, come fare dunque? Dopo alcune prove in cui provavo a capire cosa potesse influenzare il calcolo di soundex ho deciso di provare metaphone.

Metaphone produce un hash variabile (prima differenza con soundex) generato conoscendo le regole di pronuncia della lingua inglese inglese (seconda differenza); le parole utilizzate non sono solo inglesi quindi l’hash potrebbe essere non completamente corretto anche perchè la lingua inglese ha molti termini con una pronuncia simile se non uguale però se serve un hash che non varia per cambiamenti minimi della parola, potrete come sto provando io, provare a concatenare gli effetti di soundex e metaphone per avere un unico hash sicuramente più affidabile del solo soundex.

Per controlli più accurati si può utilizzare la distanza di Levenshtein ovvero il numero minimo (distanza di caratteri) di operazioni (rimozione, aggiunta, spostamento ed eliminazione) che servono per uguagliare due stringhe. In PHP vi è l’omonima funzione:

int levenshtein ( string str1, string str2 [, int cost_ins [, int cost_rep, int cost_del]] )

questa funzione è molto utile e versatile, penso che con un controllo incrociato tra gli hash prodotti dalle funzioni soundex-metaphone e dalla distanza di Levenshtein si può ottenere un buon risultato.

Fonetica nel pattern matching con php

In questo periodo per lavoro mi sto scontrando con problemi che riguardano il matrching tra stringhe. Gli strumenti per la manipolazione delle stringhe che il php mette a disposizione sono diversi, tutti molto efficaci a seconda dei casi.

Ci sono casi in cui le normali operazioni di confronto e sostituzione tra stringhe e caratteri non bastano, così ci viene in aiuto la fonetica. Le funzioni che il php ci mette a disposizione sono metaphone e soundex. Entrambe calcolano una chiave per ogni suono uguale, ovvero fornisce un impronta derivata dalla pronuncia della parola. Metaphone fornisce una chiave secondo la pronuncia inglese della parola ed ha una lunghezza variabile, essa è formata dalla prima lettera della parola e da un numero con diverse cifre. Soundex fornisce una chiave dello stesso tipo di metaphone ma di 4 caratteri, il primo carattere è la prima lettera della parola, poi ci sono 3 cifre che rappresentano il risultato dell’operazione.

Per meglio comprendere l’utilità di queste funzioni vediamo alcuni esempi:

<?
echo "\n".soundex("Viale Marconi")." ". soundex("V.le marconi");
?>

con un normale confronto le due stringhe risulterebbero differenti sfalsando dunque qualche vostro controllo, soundex invece ci fornirà due chiavi del tipo V… e V… dove al posto dei … ci sono dei numeri, uguali perchè foneticamente le due parole sono molto vicine.

PHP come shell scripting: gli stream

Nel precedente post ho accennato al fatto che utilizzando il php come linguaggio di shell scripting non sarebbe più stato possibile utilizzare i metodi $_GET e $_POST per lo scambio dati. Le esigenze in questo caso cambiano, non vi è la necessità di passare dei dati da una pagina ad un altra ma quasi sicuramente cè la necessità di interagire con l’utente. Per fare ciò possiamo usare gli stream STDIN, STDOUT e STDERR.

Il modo di usarli è il seguente:

  • si ottiene l’id dello stream: $id_stream=fopen(“/dev/stdin”,”r”);
  • si procede con il leggere i dati: $data = fread($id_strean,255);
  • si chiude lo stream a fine lettura: fclose($id_strean);

il tutto in perfetto stile ANSI C, vi consiglio di rendere il tutto procedurale per la riutilizzabilità del codice, un esempio potrebbe essere:

function input()

{

$id_stream=fopen(“/dev/stdin”,”r”);

$data = fread($id_strean,255);

fclose($id_strean);

return $data;

}

in questo modo possiamo facilmente utilizzarlo ad esempio in questo modo:

echo “\ninserisci il nome da dare al file: “;

$name= input();

PHP come shell scripting

Probabilmenti in tanti pensano che il PHP sia semplicemente un linguaggio di scripting lato server per il web, può però anche essere utilizzato come linguaggio di shell scripting esattamente come il Bash o il Perl ad esempio.

Per chi è abituato nell’utilizzo web dovrà tenere presente alcune cose, per eseguire lo script dovrà digitare da shell:

php nosme_script.php

oppure inserendo in testa ad ogni file il classico path:

#!/usr/bin/php

basterà settare il permesso di esecuzione (+x) al file per eseguirlo nel seguente modo:

./nome_script.php

Update: installando la versione attuale di php (5.1.x) l’interprete sarà php5

Il file deve iniziare e finire rispettivamente con <? e ?> tutto il codice insertito tra i due “simboli” viene interpretato come codice php, ciò che resta al di fuori viene stampato così com’è compreso eventuali righe vuote. Non sono inoltre presenti le variabili $_GET, $_POST e $_COOKIE mentre sono presenti le classiche $argc e $argv per il passaggio dei parametri.

Terminiamo questa carrellata con gli stream, sono disponibili anche in questo caso i classici STDIN, STDOUT e STDERR in lettura e scrittura, per approfondire il tutto potete consultare la pagina dedicata del manuale ufficiale.