Domanda

Arrrgh.Qualcuno sa come creare una funzione che sia l'equivalente di caratteri multibyte del comando PHP count_chars ($ string, 3)?

Tale che restituirà un elenco di SOLO UN'ISTANZA di ogni carattere univoco.Se fosse inglese e avessimo

"aaabggxxyxzxxgggghq xcccxxxzxxyx"

Restituirà "abgh qxyz" (nota che lo spazio è contato).

(L'ordine non è importante in questo caso, può essere qualsiasi cosa).

Se il kanji giapponese (non sono sicuro che tutti i browser lo supportino):

漢 漢 漢字 漢字 私 私 字 私 字 漢字 私 漢字 漢字 私

E restituirà solo i 3 kanji utilizzati:

漢字 私

Deve funzionare su qualsiasi stringa codificata UTF-8.

È stato utile?

Soluzione

Ehi Dave, non vedrai mai questo arrivare.

php > $kanji = '漢漢漢字漢字私私字私字漢字私漢字漢字私';
php > $not_kanji = 'aaabcccbbc';
php > $pattern = '/(.)\1+/u';
php > echo preg_replace($pattern, '$1', $kanji);
漢字漢字私字私字漢字私漢字漢字私
php > echo preg_replace($pattern, '$1', $not_kanji);
abcbc

Cosa, pensavi che usassi di nuovo mb_substr?

In linguaggio regex, sta cercando un carattere qualsiasi, quindi una o più istanze dello stesso carattere. La regione corrispondente viene quindi sostituita con il carattere corrispondente.

Il modificatore u attiva UTF-8 modalità in PCRE, in cui si occupa di sequenze UTF-8 invece di caratteri a 8 bit. Finché la stringa in elaborazione è già UTF-8 e PCRE è stato compilato con supporto Unicode, dovrebbe funzionare bene per te.


Ehi, indovina un po '!

$not_kanji = 'aaabbbbcdddbbbbccgggcdddeeedddaaaffff';
$l = mb_strlen($not_kanji);
$unique = array();
for($i = 0; $i < $l; $i++) {
    $char = mb_substr($not_kanji, $i, 1);
    if(!array_key_exists($char, $unique))
        $unique[$char] = 0;
    $unique[$char]++;
}
echo join('', array_keys($unique));

Questo utilizza lo stesso trucco generale del codice shuffle. Prendiamo la lunghezza della stringa, quindi usiamo mb_substr per estrarla un carattere alla volta. Quindi usiamo quel carattere come chiave in un array. Stiamo sfruttando gli array posizionali di PHP: le chiavi sono ordinate nell'ordine in cui sono definite. Una volta che abbiamo esaminato la stringa e identificato tutti i caratteri, prendiamo le chiavi e le uniamo di nuovo nello stesso ordine in cui sono apparse nella stringa. Con questa tecnica ottieni anche un conteggio dei caratteri per carattere.

Sarebbe stato molto più semplice se esistesse qualcosa come mb_str_split da abbinare a str_split .

(Nessun esempio Kanji qui, sto riscontrando un bug di copia / incolla.)


Qui, prova questo per la taglia:

function mb_count_chars_kinda($input) {
    $l = mb_strlen($input);
    $unique = array();
    for($i = 0; $i < $l; $i++) {
        $char = mb_substr($input, $i, 1);
        if(!array_key_exists($char, $unique))
            $unique[$char] = 0;
        $unique[$char]++;
    }
    return $unique;
}

function mb_string_chars_diff($one, $two) {
    $left = array_keys(mb_count_chars_kinda($one));
    $right = array_keys(mb_count_chars_kinda($two));
    return array_diff($left, $right);
}

print_r(mb_string_chars_diff('aabbccddeeffgg', 'abcde'));
/* => 
Array
(
    [5] => f
    [6] => g
)
*/

Dovrai chiamarlo due volte , la seconda volta con la stringa di sinistra a destra e la stringa di destra a sinistra. L'output sarà diverso: array_diff ti dà solo le cose sul lato sinistro che mancano da destra, quindi devi farlo due volte per ottenere l'intera storia.

Altri suggerimenti

Prova a controllare la iconv_strlen funzione della libreria standard PHP.Non posso dire le codifiche orientali, ma funziona bene per le lingue europee e dell'Europa orientale.In ogni caso dà un po 'di libertà!

$name = "My string";
$name_array = str_split($name);
$name_array_uniqued = array_unique($name_array);
print_r($name_array_uniqued);

Molto più facile.Utente str_split per trasformare la frase in un array con ogni carattere come elemento.Quindi utilizzare array_unique per rimuovere i duplicati.Abbastanza semplice.Niente di complicato.Mi piace così.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top