10
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Go - ひらがな・カタカナの相互変換

Posted at

tl;dr

  • ひらがなとカタカナは Unicode で 96 文字ずつある
  • ひらがなとカタカナの Unicode 符号位置は 96 文字ずれている
  • ひらがなの rune に 96 を足せばカタカナになる
  • カタカナの rune に 96 を引けばひらがなになる
  • rune がひらがなかどうかは unicode.In(r, unicode.Hiragana) で判定できる
  • rune がカタカナかどうかは unicode.In(r, unicode.Katakana) で判定できる

ひらがなとカタカナの Unicode 符号位置

http://www.unicodemap.org/range/62/Hiragana/http://www.unicodemap.org/range/63/Katakana/ が見やすい。
それぞれ 0x3041 と 0x30a1 からはじまる。

実装コード

HiraganaToKatakana 関数は文字列中のひらがなをカタカナに変換して返す。
KatakanaToHiragana 関数は文字列中のカタカナをひらがなに変換して返す。

package kana

import (
	"unicode"
)

const (
	// http://www.unicodemap.org/range/62/Hiragana/
	hiraganaLo = 0x3041 // ぁ

	// http://www.unicodemap.org/range/63/Katakana/
	katakanaLo = 0x30a1 // ァ

	codeDiff = katakanaLo - hiraganaLo
)

// HiraganaToKatakana はひらがなをカタカナに変換する。
func HiraganaToKatakana(str string) string {
	src := []rune(str)
	dst := make([]rune, len(src))
	for i, r := range src {
		switch {
		case unicode.In(r, unicode.Hiragana):
			dst[i] = r + codeDiff
		default:
			dst[i] = r
		}
	}
	return string(dst)
}

// KatakanaToHiragana はカタカナをひらがなに変換する。
func KatakanaToHiragana(str string) string {
	src := []rune(str)
	dst := make([]rune, len(src))
	for i, r := range src {
		switch {
		case unicode.In(r, unicode.Katakana):
			dst[i] = r - codeDiff
		default:
			dst[i] = r
		}
	}
	return string(dst)
}

テストコード

package kana_test

import (
	"testing"

	"path/to/kana"
)

func TestHiraganaToKatakana(t *testing.T) {
	tests := []struct {
		input string
		want  string
	}{
		{
			input: "",
			want:  "",
		},
		{
			input: "あいうえお",
			want:  "アイウエオ",
		},
		{
			input: "アイウエオ",
			want:  "アイウエオ",
		},
		{
			input: "あいウえお",
			want:  "アイウエオ",
		},
		{
			input: "あいuえお",
			want:  "アイuエオ",
		},
		{
			input: "あいUえお",
			want:  "アイUエオ",
		},
		{
			input: "あい雨えお",
			want:  "アイ雨エオ",
		},
	}

	for i, test := range tests {
		got := kana.HiraganaToKatakana(test.input)
		if got != test.want {
			t.Errorf("[%d] got %s, but want %s", i, got, test.want)
		}
	}
}

func TestKatakanaToHiragana(t *testing.T) {
	tests := []struct {
		input string
		want  string
	}{
		{
			input: "",
			want:  "",
		},
		{
			input: "アイウエオ",
			want:  "あいうえお",
		},
		{
			input: "あいうえお",
			want:  "あいうえお",
		},
		{
			input: "アイうエオ",
			want:  "あいうえお",
		},
		{
			input: "アイuエオ",
			want:  "あいuえお",
		},
		{
			input: "アイUエオ",
			want:  "あいUえお",
		},
		{
			input: "アイ雨エオ",
			want:  "あい雨えお",
		},
	}

	for i, test := range tests {
		got := kana.KatakanaToHiragana(test.input)
		if got != test.want {
			t.Errorf("[%d] got %s, but want %s", i, got, test.want)
		}
	}
}
10
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?