Analizzatore grammaticale e correttore ortografico
data di oggi: |
Corso analisi logica e semantica in php |
Ci poniamo, ora, il problema di come effettuare l'analisi delle parole contenute in una certa frase e verificare se le parole sono scritte in modo corretto.
Dividiamo il nostro lavoro in due parti, cioè dapprima vediamo come effettuare l'analisi delle parole in una frase data; successivamente vedremo se ogni singola parola è stata scritta in modo corretto oppure no.
Ricerca delle parole
Prendiamo ad esempio la seguente frase, che contiene un piccolo errore ortografico:
La rosa é bella.
L'errore è dovuto ad un accento acuto al posto di un accento grave nella parola: è.
Scriviamo le seguenti istruzioni in linguaggio php:
$frase1="La rosa é bella";
$spazi="/[\s]+/";
$parola= preg_split($spazi, $frase1);
Nella prima istruzione:
$frase1="La rosa é bella";
abbiamo memorizzato la nostra frase nella variabile $frase1.
Si tratta ora di dividere la nostra frase isolando ciascuna delle quattro parole e memorizzarla in una variabile. Notiamo che tra una parola e l'altra è presente uno spazio vuoto, per cui definiamo una variabile php:
$spazi="/[\s]+/";
che chiamiamo $spazi e in cui vi memorizziamo una espressione regolare. Per espressione regolare si intende una espressione in codice che ha un preciso significato.
Per esempio:
[0-9] significa una qualunque cifra numerica che va da 0 a 9, cioè un qualunque numero del sistema decimale.
[a-zA-Z] significa una qualunque lettera dell'alfabeto che va da a-z per le lettere minuscole e da A-Z per le lettere maiuscole.
[\s] significa un solo spazio;
[\s]+ significa sia un solo spazio sia molti spazi consecutivi.
Nel nostro caso è preferibile usare come espressione regolare questa ultima, cioè dividiamo la nostra frase separando le parole le une dalle altre quando si incontra o uno spazio o più spazi consecutivi.
La espressione regolare la memorizziamo in una variabile per semplicità; quindi
$spazi="/[\s]+/";
vuol dire che ho memorizzato nella variabile spazi un criterio di ricerca costituito da uno o più spazi.
Infine con
$parola= preg_split($spazi, $frase1);
divido la mia frase contenuta nella variabile $frase1 utilizzando un criterio di divisione definito dalla variabile $spazi; il risultato della divisione viene memorizzato in una matrice di nome $parola i cui elementi saranno i seguenti:
$parola[0]="La";
$parola[1]="rosa";
$parola[2]="é";
$parola[3]="bella";
Da questo momento in poi posso usare la matrice $parola come un insieme di variabili, ciascuna delle quali contiene nell'ordine una parola delle tante contenute nella frase di partenza.
Quando un programma è molto complesso è consigliabile utilizzare le funzioni. Le funzioni sono una parte di codice php che non vengono eseguite subito ma vengono eseguite vanno ne viene richiesto l'utilizzo in fase di programmazione. La funzione termina con } senza il punto e virgola.
Una prima funzione per leggere i dati può essere la seguente:
function leggodati($frase1) {
global $parola;
$spazi="/[\s]+/";
$parola= preg_split($spazi, $frase1);
}
questa è una funzione che mi esegue la divisione di una frase memorizzata in $frase1, me la divide in tanti elementi quante sono le parole contenute nella frase e memorizza ogni parola in un elemento della matrice $parola.
Per rendere il dato utilizzabile occorre inserire all'inizio della funzione:
global $parola;
che significa che la matrice $parola deve essere disponibile anche al di fuori della funzione, cioè è una variabile globale.
Una volta effettuata la scomposizione della nostra frase in tante parole possiamo procedere alla analisi ortografica di ciascuna parola per vedere se è scritta in modo corretto.
Anche qui utilizzeremo una funzione che chiameremo ortografia() la quale farà l'analisi ortografica di ciascuna parola. Per inviare ciascuna parola al controllo ortografico uso un ciclo for, tipo il seguente
// mando al controllo della funzione "ortografia()" ogni singola parola del periodo
for( $contatore=0; $contatore<99; $contatore++){
ortografia($parola[$contatore]);
};
Da questo ciclo for desumiamo un numero 99 scelto a piacere come limite massimo delle parole da mandare al controllo ortografico; questo è un limite di sicurezza, per evitare un blocco del programma se le parole riscontrate fossero eccessive. Di conseguenza la nostra funzione leggodati() diventa la seguente:
function leggodati($frase1) { global $parola; $spazi="/[\s]+/"; $parola= preg_split($spazi, $frase1); // mando al controllo della funzione "ortografia()" ogni singola parola del periodo for( $contatore=0; $contatore<99; $contatore++){ ortografia($parola[$contatore]); };
}
|
La funzione ortografia può essere la seguente:
function ortografia($nome) {
global $dato1,$parola2,$parola3,$dato1,$ortografia1,$ritorno;
$ritorno="<br>";
$a1= strtolower(substr($nome,0,1));
$nomefile="/correttore/dati/".$a1."lunghezza.txt";
$fp= fopen($nomefile,"r");
$lunghezza= fgets($fp,5096);
fclose($fp);
$lunghezza= trim($lunghezza);
$nomefile="/correttore/dati/".$a1."nomi.txt";
$fp= fopen($nomefile,"r");
for( $t3=0; $t3<$lunghezza; $t3++){
$linea1=fgets($fp,5096);
$posizio1000=strrpos($linea1,";");
$linea1= substr($linea1,0,$posizio1000 + 1);
$parola2= explode(";",$linea1);
$parola3= explode(",", $parola2[0]);
// ho trovato la parola nel dizionario
if($parola3[0]==$nome) {
$dato1.=trim($linea1).$ritorno;
fclose($fp);
return;
};
};
fclose($fp);
// segnalo parola non riconosciuta
$ortografia1 .='Errore: "'.$parola[$contatore].'" è una parola non presente in questo dizionario o con errori di scrittura!'.$ritorno;
}
E' un funzione piuttosto complessa, ma vediamo di spiegarlo in modo semplice.
Intanto con:
global $dato1,$parola2,$parola3,$dato1,$ortografia1,$ritorno;
dichiaro quelle che saranno le variabili globali, cioè disponibili anche al di fuori della funzione.
$dato1 è una variabile che contiene l'intero rigo dell'analisi grammaticale della parola in oggetto;
$parola2 è una matrice che contiene una sola delle tante possibili analisi grammaticali della stessa parola;
Qui è bene spiegarsi; vediamo la seguente parola: "che", come risulta nel dizionario delle parole:
che,pronome,comune,comune,terza,relativo;che,congiunzione;che,aggettivo,comune,comune;Pietro,De
Paolis
cioè la parola che può essere sia un pronome sia una congiunzione che un aggettivo. Ognuno dei significati è separato dall'altro con un punto e virgola; la virgola, invece, separa ciascun termine dell'analisi grammaticale. Dopo l'ultimo punto e virgola è memorizzato il nome dell'operatore che ha effettuato il salvataggio nel dizionario delle parole.
Per cui in questo caso, otterremo:
$dato1="che,pronome,comune,comune,terza,relativo;che,congiunzione;che,aggettivo,comune,comune";
$parola2[0]="che,pronome,comune,comune,terza,relativo";
$parola2[1]="che,congiunzione";
$parola2[2]="che,aggettivo,comune,comune";
Quanto a $parola3 essa contiene l'analisi grammaticale della $parola2[0] separata nei suoi componenti, e precisamente:
$parola3[0]="che";
$parola3[1]="pronome";
$parola3[2]="comune";
$parola3[3]="terza";
$parola3[4]="relativo";
Inoltre $ortografia1 contiene tutti gli errori di ortografia riscontrati durante il lavoro di controllo ortografico. Detto questo vediamo come ricavare da una parola data il nome del file che lo contiene.
Nome del file
Supponiamo che la parola da controlla sia rosa; per ricavare il nome del file uso le seguenti istruzioni:
$a1= strtolower(substr($nome,0,1));
$nomefile="/correttore/dati/".$a1."lunghezza.txt";
Cioè con:
$a1= strtolower(substr($nome,0,1));
mi isolo la prima lettera del nome rosa, cioè la lettera r e la metto nella variabile $a1. Importante che la lettera sia minuscola per cui uso strtolower, cioè faccio in minuscolo tutto il nome e prendo il primo carattere a sinistra.
Poi con:
$nomefile="/correttore/dati/".$a1."lunghezza.txt";
metto nella variabile $nomefile il nome completo del file partendo dalla radice, cioè il segno /, con le varie cartelle in cui è contenuto, cioè la cartella correttore al cui interno vi è la cartella dati; ed infine il nome del file ottenuto aggiungendo alla lettera r la parola lunghezza, cioè:
/correttore/dati/rlunghezza.txt
Lunghezza del file
Con le tre istruzioni:
$fp= fopen($nomefile,"r");
$lunghezza= fgets($fp,5096);
fclose($fp);
Apro in lettura il file rlunghezza.txt, mi leggo la prima riga e la memorizzo nella variabile $lunghezza.
D'ora in poi in $lunghezza è contenuto un numero che mi indica il numero di parole memorizzate in rnomi.txt.
Siccome vi posso essere degli spazi uso:
$lunghezza= trim($lunghezza);
in modo da togliere eventuali spazi a destra e a sinistra.
Ricerca della parola
Nella ricerca della parola nel dizionario sono possibili due soluzioni; o il nome esiste e quindi mostro l'analisi grammaticale; oppure non esiste e segnalo un errore nella variabile $ortografia1.
Dopo aver aperto in lettura il file rnomi.txt con le istruzioni:
$nomefile="/correttore/dati/".$a1."nomi.txt";
$fp= fopen($nomefile,"r");
Con un ciclo for leggo ogni riga del file:
$linea1=fgets($fp,5096);
$posizio1000=strrpos($linea1,";");
$linea1= substr($linea1,0,$posizio1000 + 1);
$parola2= explode(";",$linea1);
$parola3= explode(",", $parola2[0]);
salvo i diversi valori nelle matrici $parola2 e $parola3, e con una if vado a vedere se il nome coincide:
if($parola3[0]==$nome) {
$dato1.=trim($linea1).$ritorno;
fclose($fp);
return;
};
se è uguale al nome passato, cioè $nome, memorizzo in $dato1 l'intero rigo dell'analisi grammaticale trovata.
Altrimenti con:
$ortografia1 .='Errore: "'.$parola[$contatore].'" è una parola non presente in questo dizionario o con errori di scrittura!'.$ritorno;
segnalo in $ortografia1 che il nome non esiste o vi è un errore di ortografia.
Un intero listato può essere il seguente:
<html>
<head> <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> <meta name="GENERATOR" content="Microsoft FrontPage 4.0"> <meta name="ProgId" content="FrontPage.Editor.Document"> <title>primo.php</title> </head> <body background="../../../immagini/sfondo2.jpg"> <script language="php"> function leggodati($frase1) { global $parola; $spazi="/[\s]+/"; $parola= preg_split($spazi, $frase1); $numeroparole=count($parola); // mando al controllo della funzione "ortografia()" ogni singola parola del periodo for( $contatore=0; $contatore<$numeroparole; $contatore++){ ortografia($parola[$contatore]); }; } function ortografia($nome) { global $dato1,$parola2,$parola3,$dato1,$ortografia1,$ritorno; $ritorno="<br>"; $a1= strtolower(substr($nome,0,1)); $nomefile="/correttore/dati/".$a1."lunghezza.txt";$fp= fopen($nomefile,"r"); $lunghezza= fgets($fp,5096); fclose($fp); $lunghezza= trim($lunghezza); $nomefile="/correttore/dati/".$a1."nomi.txt"; $fp= fopen($nomefile,"r"); for( $t3=0; $t3<$lunghezza; $t3++){ $linea1=fgets($fp,5096); $posizio1000=strrpos($linea1,";"); $linea1= substr($linea1,0,$posizio1000 + 1); $parola2= explode(";",$linea1); $parola3= explode(",", $parola2[0]); // ho trovato la parola nel dizionario if($parola3[0]==$nome) { $dato1.=trim($linea1).$ritorno; fclose($fp); return; }; }; fclose($fp); // segnalo parola non riconosciuta $ortografia1 .="Errore: $nome è una parola non presente in questo dizionario o con errori di scrittura!".$ritorno; } leggodati($contenuto); print("Paole trovate:<br> $dato1"); print("Errori:<br> $ortografia1"); </script> <font color="#FF00FF" size="5" face="Verdana">Analizzatore grammaticale</font> <form method="POST" action="primo.php"><textarea rows="5" name="contenuto" cols="29" style="font-size: 14 pt; background-image: url('../../../immagini/sfondo3.gif')"></textarea><input type="submit" value="Analizza" > </form> </body> </html>
|
Listato di primo.php |
Vi sono sicuramente numerosi errori, comunque per alcune parole funziona perfettamente.
2007
Corso analisi logica e semantica
prof. Pietro De Paolis