6

全角と全角の日本語文字を検証する必要がある日本のプロジェクトがあります。全角で14文字、全角で7文字が許可されます。

それを実装する方法を知っている人はいますか?

今私のモデルで

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

良い選択ではありません

私は現在ror2.3.5を使用しています。全幅と半幅の両方を使用できます

4

2 に答える 2

11

まず、全角(全角)と全角(せる)の概念は、日本語の2種類の文字にのみ存在します。

  • ローマ字(つまりラテン)
  • カタカナのキャラクター

同様の概念は韓国のハングルにも存在しますが、日本のひらがなにも漢字にも存在しません。

カタカナの場合、半角文字には独自のUnicodeコードポイントがあり、全角文字の半分のサイズでレンダリングされますが、それ以外の形状は同じです。例:

全幅「ka」:カ<br>半幅「ka」: </ p>

結合文字(つまり、ガのような発音区別符号を含む)は、半値幅バージョンには存在しません。これらは、2つの別々の文字としてエンコードする必要があります。(2つのコードポイントのこれらの組み合わせは、文字の組み合わせと見なされ、通常は1つとしてレンダリングされることに注意してください。)

ローマ字(ラテン)文字の場合、通常のASCII文字は半値幅と呼ばれますが、Unicodeの日本語コード範囲(および従来の日本固有の文字セット)は、全幅バージョンに個別のコード範囲を提供します。例:

全幅:L <br>半幅:L

非ASCIIラテン語から派生した文字(ドイツ語のウムラウトなど)やアクセント付きバージョンには、全幅バージョンは存在しません。ただし、数字や一部の句読文字には存在します。

繰り返しますが、ひらがなと漢字には半値幅バージョンがありません。

文字が全幅文字か半幅文字かを確認するには、コードポイントを関連するコード範囲と比較します。範囲は次のとおりです。

半幅カタカナ:0xff61から0xff9f
全角カタカナ:0x30a0から0x30ff
半幅ローマ:0x21から0x7e(これはASCII)
全角ローマ:0xff01から0xff60
ひらがな:0x3041から0x309f
漢字(つまり、統一された表意文字の範囲):0x4e00から0x9fcc

これは、文字ごとにチェックを実行する単純なRubyプログラムです。

# -*- 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

その他の注意事項

  1. 上記のコード範囲は、各文字タイプの公式Unicode範囲です(Unicode全角形およびUnicodeひらがなを参照)。これらには、古い/従来の形式または特殊な句読文字である文字の特定の全幅/半幅バージョンが含まれます。Webフォームで一般的に使用される文字(たとえば、ユーザーが名前を入力するため)のみが必要な場合は、範囲を少し狭くすることをお勧めします。

  2. 推奨事項:これがユーザーが名前を入力できるWebフォームの場合は、半幅または全幅を確認するだけでなく、もう少しやりたいこともあります。それは日本のウェブサイトや登録フォーム、特にで非常に一般的です。銀行の場合、名前を純粋な半幅(通常はラテン語)または純粋な全幅(通常はカタカナ)で入力するように要求します。残念ながら、これによりデータの入力が非常に不便になります。日本語入力方式を有効にすると、ラテン文字が全幅バージョンで出力されることが多く、純粋な半幅ではないため、Webフォームはデータを拒否します。拒否するのではなく、自動的に変換する必要があります必要な形に。これは、あるコード範囲から別のコード範囲に変換することで(関連する定数を追加するだけで)簡単に実装でき、人々の生活をはるかに楽にします。

于 2013-03-27T03:09:22.213 に答える
5

次のコード、これまでに指定した正確な要件を最短時間で満たすために、あなたを一線を越えて押し進める可能性があります。これは、日本語の文字列の内容を決定する際に多くの便利な方法を提供するMoji gem日本語のドキュメント)を使用しています。

全角文字のみで構成されるaで最大14文字を検証し、nameそれ以外の場合は最大7文字を検証します(全角文字と全角文字の組み合わせを含む名前、つまり全角文字が1つでも存在する名前を含む)文字列の幅文字により、文字列全体が「全角」と見なされます。name

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

行われた仮定

  1. システム内のデータエンコーディングはUTF-8であり、データベースにそのまま保存されます。さらに必要な再エンコード(データをレガシーシステムに渡すためなど)は、別のモジュールで実行されます。
  2. データがデータベースに保存される前に全角文字の自動変換は行われません。つまり、レガシーシステムの統合、実際のユーザー入力の適切な保存(!)、および/または美的理由により、全角文字はデータベースで許可されます。半角文字の値(!)
  3. 全角文字の発音区別符号は、それ自体の別個の文字として扱われます(つまり、文字列の長さを決定する目的で、1文字と見なされるために1文字と3文字の構文解析は行われません)。
  4. 指定する名前フィールドは1つだけで、たとえば、今日では非常に一般的な4つ(名前、名前のふりがな、名前、名前のふりがな)ではあり ませ
于 2013-03-27T07:21:29.550 に答える