2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

C#で半角カタカナを全角カタカナに変換する

Last updated at Posted at 2024-01-16

はじめに

半角カタカナは何かと使い勝手が悪い文字ですので、全角カタカナに置き換えたいと思います。
但し、他の半角文字(数字やアルファベット)は変換したくありません。半角なら半角、全角なら全角のままにしたいので、StrConvを使いませんでした。
いろいろなやり方があると思いますが、文字コードで範囲を指定するなどのテクニカルな方法は避け、べたな方法で対処しました。

定数宣言

変換元のkanakeysと変換後のkanavaluesをstaticに用意します。
濁音、半濁音の扱いが面倒です。
また、存在チェックのためだけに、static List kanakeyListを用意しました。
なお、ヰヱの半角文字は無いみたいです。

private static readonly string[] kanakeys = { "ヴ", "ガ", "ギ", "グ", "ゲ", "ゴ", "ザ", "ジ", "ズ", "ゼ", "ゾ", "ダ", "ヂ", "ヅ", "デ", "ド", "バ", "ビ", "ブ", "ベ", "ボ", "パ", "ピ", "プ", "ペ", "ポ", "ア", "イ", "ウ", "エ", "オ", "カ", "キ", "ク", "ケ", "コ", "サ", "シ", "ス", "セ", "ソ", "タ", "チ", "ツ", "テ", "ト", "ナ", "ニ", "ヌ", "ネ", "ノ", "ハ", "ヒ", "フ", "ヘ", "ホ", "マ", "ミ", "ム", "メ", "モ", "ヤ", "ユ", "ヨ", "ラ", "リ", "ル", "レ", "ロ", "ワ", "ヲ", "ン", "ャ", "ュ", "ョ", "ァ", "ィ", "ェ", "ォ", "゙", "゚", "、", "。", "ー" };
private static readonly string[] kanavalues = { "ヴ", "ガ", "ギ", "グ", "ゲ", "ゴ", "ザ", "ジ", "ズ", "ゼ", "ゾ", "ダ", "ヂ", "ヅ", "デ", "ド", "バ", "ビ", "ブ", "ベ", "ボ", "パ", "ピ", "プ", "ペ", "ポ", "ア", "イ", "ウ", "エ", "オ", "カ", "キ", "ク", "ケ", "コ", "サ", "シ", "ス", "セ", "ソ", "タ", "チ", "ツ", "テ", "ト", "ナ", "ニ", "ヌ", "ネ", "ノ", "ハ", "ヒ", "フ", "ヘ", "ホ", "マ", "ミ", "ム", "メ", "モ", "ヤ", "ユ", "ヨ", "ラ", "リ", "ル", "レ", "ロ", "ワ", "ヲ", "ン", "ャ", "ュ", "ョ", "ァ", "ィ", "ェ", "ォ", "゛", "゜", "、", "。", "ー" };
private static readonly List<char> kanakeyList = new List<char> { 'ア', 'イ', 'ウ', 'エ', 'オ', 'カ', 'キ', 'ク', 'ケ', 'コ', 'サ', 'シ', 'ス', 'セ', 'ソ', 'タ', 'チ', 'ツ', 'テ', 'ト', 'ナ', 'ニ', 'ヌ', 'ネ', 'ノ', 'ハ', 'ヒ', 'フ', 'ヘ', 'ホ', 'マ', 'ミ', 'ム', 'メ', 'モ', 'ヤ', 'ユ', 'ヨ', 'ラ', 'リ', 'ル', 'レ', 'ロ', 'ワ', 'ヲ', 'ン', 'ャ', 'ュ', 'ョ', 'ァ', 'ィ', 'ェ', 'ォ', '゙', '゚', '、', '。', 'ー' };

メソッド

        public static string KanaToFull(string target)
        {
            Debug.WriteLine("in: [" + target + "]");
            DateTime dtStart = DateTime.Now;//開始

            if(target.Where(x => kanakeyList.Contains(x)).Count() > 0)//対象かどうかチェック
            {
                for (int idx = 0; idx < kanavalues.Length; idx++)
                {
                    target = target.Replace(kanakeys[idx], kanavalues[idx]);
                }
            }

            DateTime dtEnd = DateTime.Now;//終了
            TimeSpan timeSpan = dtEnd - dtStart;//速度測定
            Debug.WriteLine("out:[" + target + "]");
            Debug.WriteLine(timeSpan.TotalMilliseconds.ToString());
            return target;
        }

Debug.WriteLine、DateTime、TimeSpan は速度測定用なので、実装時は不要です。

そうすると本体は、以下だけになります。

            if(target.Where(x => kanakeyList.Contains(x)).Count() > 0)//対象かどうかチェック
            {
                for (int idx = 0; idx < kanavalues.Length; idx++)
                {
                    target = target.Replace(kanakeys[idx], kanavalues[idx]);
                }
            }

少しでも速度を上げるために、kanakeyListに含まれる文字がtargetに存在するかどうかのチェックを行っています。必ず半角カナがあるのでチェックの必要が無いtargetが短くて意識する必要が無い、などであれば、却って速度を低下させるので、取り除いても良いかと思います。

後は、kanakeysの文字列をkanavaluesの文字列にReplaceしているだけです。
kanavalues.Length回Replaceを実行するので速度が気になりますね。

速度測定

試みに、吾輩は猫であるの冒頭2600文字程度を、漢字を除いて半角カナに変換して実行したところ、私の環境では

1回目 2回目 3回目 4回目 5回目
約5ms 約0.3ms 約0.3ms 約0.3ms 約0.2ms
約5ms 約0.4ms 約0.3ms 約0.3ms 約0.2ms

でした。一旦終了させて再実験しても1回目は少し遅いので、文書が変数上に残っているのかも知れないと思い、舞姫の冒頭約2000文字程度を同じように半角化して代わりばんこに実行したところ、

1回目 2回目 3回目 4回目
約5ms/猫 約0.3ms/舞 約0.3ms/猫 約0.1ms/舞
約3ms/舞 約0.4ms/猫 約0.2ms/舞 約0.2ms/猫

でした。ひょっとしたら、staticな配列であっても呼び出されるまでメモリ上にはおらず、初回ロードのコストなのかも知れません。検証するのも面倒なのでやりませんけど。

例えば100回このメソッドを呼ぶことがあったとして、初回ロード時のコストが5ms、2回目以降のコストが0.3msとすれば、5+0.3*99≒35ms、0.035秒なので、特に速度を意識する必要はなさそうに思います。

補足

指摘頂いているStringBuilderの件、てっきりAdd系しか速度向上に寄与しないと思っていて、そもそもReplace出来るとは思っていませんでした。ありがとうございます。
ListよりHashSetの方が早いですね。ちょっと雑でした。CountとAnyもそうですね。
switchの方が確かに速いのですが、ソースコードの見やすさとの兼ね合いで、Replaceを回してみました。
ご指摘ありがとうございます。

2
2
2

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
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?