Visualizzazione dei risultati da 1 a 7 su 7

Discussione: estrapolare parole

  1. #1
    Utente di HTML.it
    Registrato dal
    Aug 2004
    Messaggi
    376

    estrapolare parole

    ciao a tutti
    vi chiedo se c'è una funzione che preleva da un testo (che sia un file, un post dal form ecc.) tutte le parole che lo compongono e le metta in ordine per frequenza.
    Faccio un esempio:

    "siamo andati in montagna e il tempo era brutto ma più a valle il tempo era migliore. Ritorneremo quando sarà ancora migliore"

    Nella frase le parole "tempo" e "migliore" sono presenti due volte ciascuno, quindi in una ipotetica lista saranno al primo posto e via via tutte le altre parole

  2. #2
    Utente di HTML.it L'avatar di Misterxxx
    Registrato dal
    Oct 2003
    Messaggi
    3,702
    Io ne ho viste cose che voi umani non potreste immaginare. Navi da combattimento in fiamme al largo dei bastioni di Orione e ho visto i raggi B, balenare nel buio vicino le porte di Tannhäuser. E tutti quei momenti ... andranno ... perduti nel tempo, come lacrime nella pioggia. È tempo di morire. (Roy Batty).

  3. #3
    Moderatore di CSS L'avatar di KillerWorm
    Registrato dal
    Apr 2004
    Messaggi
    5,691
    Ciao, da quel che so, non mi pare esista nativamente una funzione unica per ottenere ciò che chiedi, a meno di non usare qualche eventuale libreria apposita per l'analisi su testi (suppongo ne esistano ma non saprei dirti di più). La questione può comunque essere risolta in svariati modi usando diverse funzioni. Comunque sia, col semplice PHP dovresti suddividere il procedimento in vari passaggi e quindi usare diverse funzioni per risolvere ciascun passaggio.

    I passaggi potrebbero essere i seguenti:

    - recuperare il testo
    Bisogna capire cosa intendi per "che sia un file, un post dal form ecc.". Ti direi che a prescindere dall'origine da cui prelevi tale testo, dovrai arrivare necessariamente ad ottenere una stringa testuale, per cui partirei da questo punto. E' chiaro poi che il processo per recuperare tale dato può risultare differente da caso a caso, a seconda del contesto, che si voglia recuperarlo da un file piuttosto che da una pagina web o magari da un database, ecc.

    Partirei quindi da un semplice:
    Codice PHP:
    $str  "siamo andati in montagna e il tempo era brutto ma più a valle il  tempo era migliore. Ritorneremo quando sarà ancora migliore"
    - non fare distinzione tra lettere minuscole e maiuscole
    Non lo hai specificato ma credo che parole come "Ciao" e "ciao" dovranno essere considerate equivalenti e conteggiate quindi assieme. In termini tecnici si può dire che il procedimento deve essere "case insensitive". In tal caso potrebbe essere necessario uniformare i dati in entrata. Può essere sufficiente convertire il testo tutto in minuscolo, usando ad esempio la funzione strtolower().

    - suddividere il testo in parole e conteggiare quante volte viene ripetuta ciascuna parola
    In realtà, a livello logico, sarebbero due passaggi distinti che vedono l'uso di una funzione tipo explode() o preg_match_all() (come consigliato da Misterxxx) o ancora con altre funzioni simili, cosi da ottenere un array contenente tutte le parole della stringa; dopo di chè usare un qualche ciclo per eseguire il conteggio di ciascuna parola.

    Tuttavia in questo caso il PHP ci viene in contro con la funzione array_count_values() che esegue entrambe i passaggi in uno solo (ottenere un array delle parole e conteggiarne la frequenza). Tale funzione infatti, partendo da una stringa, restituisce un array associativo in cui le parole trovate sono usate come chiavi (quindi come valori univoci), mentre il numero della frequenza è applicato come valore per ciascun elemento dell'array restituito.

    - riordinare gli elementi in base alla loro frequenza
    E' possibile usare la funzione arsort() per riordinare gli elementi dell'array in modo crescente secondo il loro valore. In questo caso


    Qui un semplice esempio:
    Codice PHP:
    $str  "siamo andati in montagna e il tempo era brutto ma più a valle il  tempo era migliore. Ritorneremo quando sarà ancora migliore";
    $arr str_word_countstrtolower$str ), 1'àèéìòù' );
    $out array_count_values$arr );
    arsort$out);
    print_r$out ); 
    Il risultato sarà:
    Codice PHP:
    Array
    (
        [
    tempo] => 2
        
    [il] => 2
        
    [era] => 2
        
    [migliore] => 2
        
    [siamo] => 1
        
    [a] => 1
        
    [sarà] => 1
        
    [quando] => 1
        
    [ritorneremo] => 1
        
    [valle] => 1
        
    [ma] => 1
        
    [più] => 1
        
    [andati] => 1
        
    [brutto] => 1
        
    [e] => 1
        
    [montagna] => 1
        
    [in] => 1
        
    [ancora] => 1

    Vedi se può essere utilizzato per ciò che ti serve; poi, ripeto, è possibile risolvere in tanti altri modi.
    Installa Forum HTML.it Toolset per una fruizione ottimale del Forum

  4. #4
    Utente di HTML.it
    Registrato dal
    Aug 2004
    Messaggi
    376
    ottimo! era proprio ciò che mi serviva: ho però i seguenti dubbi.

    Il testo non l'ho specificato ma $str la ottengo da un form o anche da un db e quello ce l'ho.

    Non ho capito però come dire a array_count_values() di escludere determinate parole oppure di escludere parole che, esempio, sono inferiori a 3 caratteri: in, la, be, da, di, apice, e così via.
    Delle vocali accentate che hai messo ho tenuto solo le due e accentate.

  5. #5
    Moderatore di CSS L'avatar di KillerWorm
    Registrato dal
    Apr 2004
    Messaggi
    5,691
    Non ho capito però come dire a array_count_values() di escludere determinate parole oppure di escludere parole che, esempio, sono inferiori a 3 caratteri: in, la, be, da, di, apice, e così via.
    Quella funzione restituisce tutti gli elementi senza esclusione alcuna. Puoi agire in due modi, o cicli l'array ottenuto e rimuovi gli elementi che non ti servono, oppure utilizzi preg_match_all() (come Misterxxx ha visto bene di consigliarti) al posto di str_word_count() in modo da poter "customizzare" la ricerca come meglio ti pare con un'espressione regolare.

    Faccio un errata corrige del terzo (doppio) passaggio che ho indicato: in effetti in quel passaggio vanno considerate effettivamente due azioni distinte, la prima è appunto il recupero di un array contenente le parole trovate a partire dalla stringa data (questo è stato fatto con str_word_count()), e successivamente la seconda azione in cui sono contate le ripetizioni di ciascun elemento (con array_count_values()).

    Si tratta quindi di due passaggi distinti che, non so perché, ho accomunato in un unico passaggio supponendo erroneamente che array_count_values() sbrigasse entrambe le cose. Chiaramente nell'esempio i due passaggi sono identificabili in modo distinto.

    Ad ogni modo, anziché str_word_count() puoi usare appunto preg_match_all() in questo modo:
    Codice PHP:
    $str  "siamo andati in montagna e il tempo era brutto ma più a valle il tempo era migliore. Ritorneremo quando sarà ancora migliore";
    preg_match_all('/\b[a-zèé]{3,}\b/u'strtolower$str ), $arr);
    $out array_count_values$arr[0] );
    arsort$out);
    print_r$out ); 
    Il risultato è:
    Codice PHP:
    Array
    (
        [
    tempo] => 2
        
    [era] => 2
        
    [migliore] => 2
        
    [andati] => 1
        
    [montagna] => 1
        
    [brutto] => 1
        
    [valle] => 1
        
    [ritorneremo] => 1
        
    [quando] => 1
        
    [ancora] => 1

    Chiaramente con preg_match_all puoi impostare la ricerca come meglio credi.
    Nello specifico il pattern da me usato ha questo significato:

    \b word boundary, cioè qualsiasi cosa che identifica l'inizio o la fine di una parola
    [a-zèé] qualsiasi carattere compreso nella classe specificata (cioè qualsiasi lettera dalla a alla z e i caratteri è, é){3,} quantificatore, trova una serie di 3 o più elementi della precedente indicazione
    \b word boundary

    Infine il modificatore u (unicode) sta ad indicare che i caratteri della stringa sono considerati secondo la codifica UTF-16. In questo caso è necessario dal momento che ci sono caratteri accentati, altrimenti non riconosciuti.

    Come da te richiesto, vengono considerate tutte le parole di 3 o più lettere che possono contenere inoltre delle e accentate.
    E' chiaro che con un'espressione regolare potresti specificare tutto ciò che ti pare come meglio credi, come ad esempio escludere determinate parole; il limite sta giusto nella tua immaginazione. A te provare...

    Buon proseguimento.
    Ultima modifica di KillerWorm; 01-12-2018 a 23:12
    Installa Forum HTML.it Toolset per una fruizione ottimale del Forum

  6. #6
    Utente di HTML.it
    Registrato dal
    Aug 2004
    Messaggi
    376
    perfetto, sei stato molto chiaro e bravo!

    Userò l'ultima modifica proposta così posso applicare eventualmente altri filtri in preg_match_all

    Grazie.

  7. #7
    Moderatore di CSS L'avatar di KillerWorm
    Registrato dal
    Apr 2004
    Messaggi
    5,691
    Installa Forum HTML.it Toolset per una fruizione ottimale del Forum

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.