2013-03-26 13 views
7

Ho un progetto giapponese che deve convalidare un carattere giapponese a metà larghezza e a larghezza intera, 14 caratteri a metà larghezza e 7 caratteri a larghezza intera.Convalida il carattere giapponese nel callback del record attivo

C'è qualcuno che sa come implementarlo?

In questo momento sul mio modello

class Customer 
    validates_length_of :name, :maximum => 14 
end 

non è una buona scelta

Attualmente sto usando ror 2.3.5 Sia fullwidth e metà larghezza può essere utilizzato

+0

Non so quali siano i caratteri giapponesi a metà larghezza e a larghezza intera. È qualcosa che devo capire per rispondere alla domanda? –

+2

@garbagecollection Molto probabilmente sì. [Questa risposta sembra correlata] (http://stackoverflow.com/a/4684278/477878) anche se è una risposta sulla larghezza del carattere per la regolazione. –

+0

sì, il font mi sembra che la larghezza di metà è il rapporto 2: 1 mentre la larghezza totale è il rapporto 1: 1, controllo la dimensione dei byte ma entrambi sono 3 – valrecx

risposta

5

Il seguente codice di può solo voi spingere oltre la linea per soddisfare il requisito esatto che avete finora specificato nel minor tempo possibile. Esso utilizza il Moji gem (Japanese documentation), che dà un sacco di metodi di convenienza nel determinare il contenuto di una stringa di lingua giapponese.

Si convalida un massimo di 14 caratteri in un name che solo costituito da caratteri a mezza larghezza, e un massimo di 7 caratteri per name s altrimenti (compresi i nomi che contengono una combinazione di caratteri e mezza a larghezza intera cioè la presenza anche di un carattere a larghezza intera nella stringa farà sì che l'intera stringa venga considerata come "full-width").

class Customer 

    validates_length_of :name, :maximum => 14, 
    :if => Proc.new { |customer| half_width?(customer.name) } 
    validates_length_of :name, :maximum => 7 
    :unless => Proc.new { |customer| half_width?(customer.name) } 

    def half_width?(string) 
    Moji.type?(string, Moji::HAN_KATA) 
    end 

end 

assunzioni fatte:

codifica
  1. dati all'interno del sistema è UTF-8, e viene memorizzato come tale nella banca dati; qualsiasi ulteriore ricodifica necessaria (ad esempio per il trasferimento dei dati a un sistema legacy, ecc.) viene eseguita in un altro modulo.
  2. Nessuna conversione automatica di caratteri da metà a intera larghezza prima che i dati vengano salvati nel database, ovvero caratteri a mezza larghezza sono consentiti nel database per ragioni forse dell'integrazione del sistema legacy, conservazione corretta dell'input dell'utente reale (!), E/o valore estetico di caratteri a mezza larghezza (!)
  3. I segni diacritici in caratteri a mezza larghezza vengono considerati come un carattere separato (ovvero nessuna analisi di カ e ゙ da considerare un carattere per determinare la lunghezza della stringa)
  4. C'è solo un campo nome specificato e non, diciamo, quattro (per cognome, cognome furigana, nome dato, nome dato furigana) che è abbastanza comune al giorno d'oggi.
+0

+1 per l'utilizzo di una libreria – jogojapan

10

Prima di tutto, il concetto di larghezza completa (全 角) e metà larghezza (半角) esiste solo per due tipi di caratteri in giapponese:

  • Caratteri romani (ad es. Latino)
  • Katakana caratteri

Esiste un concetto simile per il coreano Hangul, ma non per il giapponese Hiragana, nè per Kanji.

Per Katakana, i caratteri a mezza larghezza hanno i loro punti di codice Unicode e vengono visualizzati a metà delle dimensioni dei caratteri a larghezza intera, sebbene in caso contrario abbiano una forma identica. Esempio:

spessore pieno "ka": カ
Simbolo alfabeto "ka": カ

caratteri combinati (cioè con diacritics come ガ) non esiste in versioni Mezza-; devono essere codificati come due caratteri separati: カ + ゙, che è probabilmente la ragione per cui nel tuo compito il doppio dei caratteri è consentito per la larghezza di metà. (Si noti che queste combinazioni di due punti di codice sono considerate come personaggi che combinano e di solito reso come uno.)

Per romana (latina) caratteri, i soliti caratteri ASCII sono chiamati metà larghezza, ma la gamma di codice giapponese di Unicode (così come i tradizionali set di caratteri specifici per il Giappone) forniscono un intervallo di codice separato per le versioni a larghezza piena. Esempio:

spessore pieno: L
Mezza-larghezza: non esistono L

versioni Tutta Larghezza per i caratteri non-ASCII Latin-derivati ​​(come ad esempio dieresi tedesche), né per le versioni accentate. Esse, tuttavia, esistono per i numeri e alcuni caratteri di punteggiatura.

Ancora una volta, Hiragana e Kanji non hanno versioni della larghezza di metà.

Per verificare se un carattere è a larghezza intera oa metà larghezza, confrontare il punto di codice con l'intervallo di codice rilevante.Gli intervalli sono i seguenti:

Simbolo alfabeto Katakana: 0xff61 attraverso 0xff9f
spessore pieno Katakana: 0x30a0 attraverso 0x30ff
Mezza-larghezza romana: 0x21 attraverso 0x7e (questo è ASCII)
spessore pieno romana: 0xff01 attraverso 0xff60
Hiragana: 0x3041 attraverso 0x309f
Kanji (ovvero il gruppo unificato-ideogrammi): 0x4e00 attraverso 0x9fcc

Ecco un semplice programma in Ruby che esegue i controlli su una base per-carattere:

# -*- coding: utf-8 -*- 

def is_halfwidth_katakana(c) 
    return (c.ord >= 0xff61 and c.ord <= 0xff9f) 
end 

def is_fullwidth_katakana(c) 
    return (c.ord >= 0x30a0 and c.ord <= 0x30ff) 
end 

def is_halfwidth_roman(c) 
    return (c.ord >= 0x21 and c.ord <= 0x7e) 
end 

def is_fullwidth_roman(c) 
    return (c.ord >= 0xff01 and c.ord <= 0xff60) 
end 

def is_hiragana(c) 
    return (c.ord >= 0x3041 and c.ord <= 0x309f) 
end 

def is_kanji(c) 
    return (c.ord >= 0x4e00 and c.ord <= 0x9fcc) 
end 

text = "Hello World、こんにちは、半角カタカナ、全角カタカナ、fullwidth 0-9\n" 

text.split("").each do |c| 
    if is_halfwidth_katakana(c) 
    type = "halfwidth katakana" 
    elsif is_fullwidth_katakana(c) 
    type = "fullwidth katakana" 
    elsif is_halfwidth_roman(c) 
    type = "halfwidth roman" 
    elsif is_fullwidth_roman(c) 
    type = "fullwidth roman" 
    elsif is_hiragana(c) 
    type = "hiragana" 
    elsif is_kanji(c) 
    type = "kanji" 
    end 

    printf("%c (%x) %s\n",c,c.ord,type) 
end 

Ulteriori note

  1. Il codice va sopra sono il funzionario Intervalli Unicode per ciascun tipo di carattere (vedere Unicode Fullwidth forms e Unicode Hiragana). Questi includono alcune versioni a larghezza piena/mezza larghezza di caratteri che sono forme vecchie/tradizionali o caratteri speciali di punteggiatura. Se desideri solo caratteri comunemente usati nei moduli web (ad esempio perché le persone inseriscano i loro nomi), potresti voler limitare un po 'gli intervalli.

  2. Raccomandazione: se si tratta di un modulo Web in cui le persone possono inserire il proprio nome, è consigliabile eseguire un po 'più di semplice controllo di metà larghezza o larghezza intera. È estremamente comune nei siti Web giapponesi e nei moduli di registrazione, in particolare con le banche, per richiedere che le persone inseriscano il loro nome in pura larghezza di mezzo (tipicamente per il latino) o pura larghezza intera (tipicamente per Katakana). Sfortunatamente, ciò rende l'inserimento dei dati molto sconveniente. Quando il metodo di input giapponese è abilitato, i caratteri latini spesso escono in versioni a larghezza intera e il modulo Web rifiuterà quindi i dati perché non è pura larghezza di metà. Invece di rifiutare, dovrebbe convertire automaticamente a qualsiasi forma di cui ha bisogno. Puoi facilmente implementarlo traducendo da un intervallo di codici all'altro (semplicemente aggiungendo la costante pertinente) e rendendo la vita delle persone molto più semplice.

Problemi correlati