2011-04-12 23 views
8

Tengo una cadena codificada en UTF-8 que puede contener kanji de ancho completo, kana de ancho completo, kana de medio ancho, romaji, números o kawaii símbolos japoneses como ★ o ♥.Cálculo de la longitud de una cadena multibyte japonesa con kana de ancho medio en PHP

Si quiero la longitud que uso mb_strlen() y cuenta cada uno de estos como 1 de longitud. Lo cual está bien para la mayoría de los propósitos.

Pero, un cliente japonés me ha pedido que solo cuente kana de ancho medio como 0.5 (para la longitud máxima de un campo de texto) porque aparentemente así es como lo hacen los sitios web japoneses. Lo hago uso de mb_strwidth() que cuenta todo lo ancho como 2, y la mitad de ancho que 1, entonces yo simplemente dividir por 2.

Sin embargo, este método también cuenta caracteres romaji como 1 así que algo como Chocアイス contaría como 7 .. entonces dividiría por 2 para dar cuenta de kanji y obtendría 3.5. pero en realidad quiero 5.5 (4 para el Romaji + 1.5 para los 3 kana de ancho medio).

// EDITAR: algo más de información: cualquier carácter (incluso no kana) que tenga un punto y medio debe ser 1 para el ancho completo y 0.5 para el ancho medio. por ejemplo, personajes como ¥、3@( todos deben ser 1, pero personajes como ¥,[email protected]( debe ser todo 0,5

// EDITAR EXTRA: símbolos como ☆ y ♥ deben ser 1, pero el/2 método mb_strwidth devolverlos como 0,5

¿Hay alguna manera estándar en que los sistemas japoneses cuenten la longitud de la cadena? ¿O todo el mundo simplemente recorre sus cadenas y cuenta los caracteres que no coinciden con las reglas de ancho estándar?

+1

Mi idea espontánea sería usar 'mb_strlen' como de costumbre y restar el número de ocurrencias de caracteres entre los puntos de código Unicode FF61 y FF9F. Yo podría resolver esto en una respuesta completa después ... – deceze

Respuesta

0

Entonces, no encontré ninguna respuesta para esto.

Lo arreglé iterando literalmente y revisando cada carácter y aplicando manualmente las reglas de recuento que mi cliente solicitó.

3

Una forma es convertir el katakana de ancho a todo lo ancho y restar la diferencia de anchura de la longitud original:

$raw = 'Chocアイス'; 
$full = mb_convert_kana($raw, 'K'); 
$len = mb_strlen($raw) - (mb_strwidth($full) - mb_strwidth($raw))/2; 
assert($len === 5.5); 

Sin embargo, ¿estás Seguro que debería considerar caracteres latinos básicos como de ancho completo? También existen variedades de ancho completo de caracteres latinos básicos, es decir, ¿debería considerarse Choc el mismo que Choc?

Normalmente, los caracteres como "A" y "ア" tienen un ancho de 1, pero "A" y "ア" tienen un ancho de 2 (que es lo que mb_strwidth). Sería cauteloso al tener que hackear eso.


Dado su edición, mb_strwidth (o mb_strwidth/2) hace exactamente lo que quiere.

+0

Realmente debería aclarar más; pero símbolos (♥ ☆ etc) deben ser 1, y volver 0.5 en el método mb_strwidth/2. todo es muy confuso, pero mi pregunta es realmente buscar qué "reglas estándar" son para este tipo de cosas? ¿O mi cliente lo está inventando a medida que avanza? (él es un hombre de negocios muy exitoso y experimentado). – icchanobot

+0

Sin embargo, esos símbolos (♥ ☆) no son de ancho completo. En cuanto a las reglas estándar, [Unicode TR11] (http://unicode.org/reports/tr11/) documenta cómo caracteres se clasifican como completo o medio de ancho. –

+0

Hola, soy consciente de que no tienen ancho completo según mi código, pero me han pedido que los cuente como 1 longitud. Mi cliente me aseguró a sus reglas eran estándar, y me mostró en un popular sitio web (http://www.gnavi.co.jp/) con un montón de ejemplos que han concordado con sus reglas. Esperaba que hubiera una manera más segura que yo de codificar las reglas de su explicación. Tal vez necesito encontrar Stackoverflow en japonés. – icchanobot

0

Mire el módulo Unicode::GCString de Perl: proporciona las columnas correctas para todos los Unicode, incluidas las cosas del este de Asia.

Es un componente subyacente de Unicode::LineBreak, que he encontrado absolutamente indispensable para realizar la segmentación de texto adecuado de guiones asiáticos.

Como usted bien puede imaginar, ambos están Made in Japan ™. :)

Cuestiones relacionadas