Pregunta

Arrrgh.¿Alguien sabe cómo crear una función que sea el carácter multibyte equivalente al comando PHP count_chars ($ string, 3)?

De tal manera que devolverá una lista de SOLO UNA INSTANCIA de cada personaje único.Si eso fuera inglés y tuviéramos

"aaabggxxyxzxxgggghq xcccxxxzxxyx"

Devolvería "abgh qxyz" (tenga en cuenta que el espacio se cuenta).

(El orden no es importante en este caso, puede ser cualquier cosa).

Si es kanji japonés (no estoy seguro de que todos los navegadores admitan esto):

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

Y devolverá solo los 3 kanji utilizados:

漢字 私

Debe funcionar en cualquier cadena codificada en UTF-8.

¿Fue útil?

Solución

Hola, Dave, nunca verás este venir.

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

¿Pensaste que iba a usar mb_substr de nuevo?

En expresiones regulares, busca cualquier carácter, luego una o más instancias de ese mismo carácter. Luego, la región coincidente se reemplaza con el único carácter que coincide.

El modificador u activa UTF-8 en PCRE, en el que trata con secuencias UTF-8 en lugar de caracteres de 8 bits. Siempre que la cadena que se está procesando sea UTF-8 ya y PCRE se compiló con soporte Unicode, esto debería funcionar bien para usted.


¡Oye, adivina qué!

$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));

Esto usa el mismo truco general que el código aleatorio. Tomamos la longitud de la cadena, luego usamos mb_substr para extraer un carácter a la vez. Luego usamos ese carácter como clave en una matriz. Aprovechamos las matrices posicionales de PHP: las claves se ordenan en el orden en que están definidas. Una vez que hemos revisado la cadena e identificado todos los caracteres, tomamos las llaves y los volvemos a unir en el mismo orden en que aparecieron en la cadena. También obtienes un recuento de caracteres por carácter con esta técnica.

Esto habría sido mucho más fácil si existiera algo como mb_str_split junto con str_split .

(No hay ejemplo de kanji aquí, estoy experimentando un error de copiar / pegar).


Aquí, pruébate esto para ver el tamaño:

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
)
*/

Querrá llamar a esto dos veces , la segunda vez con la cadena izquierda a la derecha y la cadena derecha a la izquierda. La salida será diferente: array_diff solo le brinda las cosas en el lado izquierdo que faltan en el derecho, por lo que debe hacerlo dos veces para obtener la historia completa.

Otros consejos

Intente comprobar la iconv_strlen función de biblioteca estándar de PHP.No puedo decir sobre las codificaciones de Oriente, pero funciona bien para los idiomas europeos y de Europa del Este.En cualquier caso, ¡da algo de libertad!

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

Mucho más fácil.El usuario str_split para convertir la frase en una matriz con cada carácter como un elemento.Luego use array_unique para eliminar duplicados.Bastante simple.Nada complicado.Me gusta así.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top