Visualizzazione dei risultati da 1 a 6 su 6

Discussione: codifica caratteri

  1. #1

    codifica caratteri

    Salve,
    ho un problema con il trattamento delle stringe in php.
    Si tratta di questo: mi occorre individuare se in una stringa ($stringa) sono presenti vocali accentate ed in caso affermativo quali e quante. Passo quindi in rassegna ogni singolo carattere con un ciclo "For" all'interno del quale questa espressione

    Codice PHP:
    if (in_array($stringa[$conta_caratteri], $v_accentate)){++$numero_accenti}; 
    dove
    $stringa è la stringa da analizzare
    $conta_caratteri è l'indice
    $v_accentate è l'array con le vocali accentate
    $numero_accenti contiene il numero di accenti trovati

    dovrebbe risolvere il problema, ma non funziona perché le vocali accentate in $stringa vengono trasformate nei classici "punti interrogativi in sfondo nero".
    La codifica del file è in UTF-8 e non posso cambiarla, ho provato in diversi i modi senza venire a capo di niente.
    Grazie a quanti mi possono aiutare a risolvere il problema.

  2. #2
    Moderatore di PHP L'avatar di Alhazred
    Registrato dal
    Oct 2003
    Messaggi
    12,503
    Benvenuto, leggi il link che ho in firma sui caratteri strani.

  3. #3
    Utente di HTML.it L'avatar di .Kurt
    Registrato dal
    Jul 2007
    Messaggi
    654
    ma non funziona perché le vocali accentate in $stringa vengono trasformate nei classici "punti interrogativi in sfondo nero".
    Per spiegarti questo comportamento devi sapere che le stringhe, in php, altro non sono che array di byte di cui php non conosce la codifica, ne gli importa di conoscerla. Quando tu fai $string = "ab"; allora è vero che $string[0] contiene "a" e $string[1] contiene "b", ma solo perché il carattere "a" e il carattere "b" sono codificati utilizzando un solo byte. In utf-8 tutti i caratteri che non occupa le prime 128 posizioni sono vengono codificati utilizzando due o più byte. (Gli unici caratteri che occupano un solo byte sono quindi solo i primi 128 caratteri ascii, che è un sottoinsieme di utf-8, e che contengono i "comuni caratteri inglesi"). Ecco quindi che parliamo di codifiche multibyte. Cosa significa questo per te? Che il carattere accentato che vuoi recuperare dalla stringa è composto da due (fino a quattro) byte, non uno. Ecco perché se accedi ai singoli byte con $stringa[$indice] ottieni quei "punti interrogativi in sfondo nero": perché quell'insieme di byte che rappresentano quel carattere hanno senso solo se presi insieme. Presi singolarmente potrebbero non puntare a nulla, o peggio, puntare ad altro.

    Sapendo questo prova a ripensare alla tua strategia, se non ti viene in mente niente ti posso dare qualche indicazione.
    Ultima modifica di .Kurt; 01-02-2015 a 01:07

  4. #4
    Grazie per il benvenuto.
    Sono comunque un frequentatore del forum e sono iscritto alla vostra newsletter. Sono comunque un utente già registrato, ma ho smarrito le credenziali e mi è sembrato più immediata una nuova iscrizione che il recupero della pass.
    Grazie ancora per il benvenuto

  5. #5
    Non so proprio quale strategia usare, potrei controllare se il carattere non ricade nelle prime 128 posizioni, ma ciò non mi direbbe di quale carattere si tratta.
    C'è da dire che con la codifica "Western European CP-1252" il problema non si pone in quanto riconosce le accentate (e non so perché), per contro si pongono altri problemi con altri caratteri come per esempio quelli dell'alfabeto greco.
    Usare altre codifiche (utf-16) col php non funziona per niente.
    A questo punto qualsiasi indicazione che potrebbe aiutarmi a risolvere il problema è ben accetta.
    Ringrazio ancora per l'attenzione prestata.

  6. #6
    Utente di HTML.it L'avatar di .Kurt
    Registrato dal
    Jul 2007
    Messaggi
    654
    C'è da dire che con la codifica "Western European CP-1252" il problema non si pone in quanto riconosce le accentate (e non so perché)
    Il motivo te l'ho spiegato. CP1252 encoda i caratteri utilizzando un singolo ottetto, al contrario di utf-8.
    Di utf-8 ti basta sapere che è una codifica multibyte e conoscere quelle 3/4 caratteristiche che ha. Quando poi lavori con delle stringhe utf-8 devi sapere cosa stai facendo, altrimenti otterrai dei risultati imprevisti. Un esempio di questo che trovi quasi per primo ovunque è:
    Codice PHP:
    $utf8_string "àbcdèfg";
    echo 
    strlen($utf8_string); // 9, non 7 
    strlen infatti conta i byte, non i caratteri, come si è abituati a pensare. Ecco quindi che ti ritroverai molto spesso ad usare al posto di queste funzioni delle altre che invece considerano l'encoding della stringa.

    In questo caso particolare non serve pensare ad un algoritmo, php ha già una funzione che fa questo lavoro: http://php.net/manual/en/function.substr-count.php
    Questa funzione (come strlen) non ha conoscenza di come la stringa che stai cercando sia codificata, lavora cercando byte, non caratteri. Quello che ti devi quindi chiedere è: con stringhe utf-8 questa funzione lavora correttamente? La risposta è si. Perché una delle caratteristiche di utf-8 è che tutti i caratteri sono codificati utilizzando un insieme unico di ottetti che quindi non sono a loro volta utilizzati per codificare un altro carattere. Non c'è quindi nessuna ambiguità a cercare dei byte (NON caratteri) in una stringa, sapendo che se li trovo è proprio quel carattere, non altro.

    codice:
    $utf8_string = "àbcdèfgàbcdèfg";
    $n = 0;
    foreach (array('è', 'à') as $char) {
        $n += substr_count($utf8_string, $char);
    }
    
    echo "Trovati: ", $n;
    Demo: http://3v4l.org/uodQ7

    Nota che esiste una funzione che fa lo stesso lavoro di substr_count e che considera il set di caratteri utilizzato, http://php.net/manual/en/function.mb-substr-count.php, ma avendo coscenza di cosa è utf-8 puoi anche scegliere di non utilizzarla e di gestire al meglio le tue stringhe. Non andare alla cieca nel trattare stringhe multibyte, mi raccomando.
    Ultima modifica di .Kurt; 01-02-2015 a 13:14

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 © 2025 vBulletin Solutions, Inc. All rights reserved.