C# Tips | 文字列処理:半角→全角

C# C#
スポンサーリンク

はじめに 「半角→全角」は“見た目とフォーマットをそろえるための技”

さっきの「全角→半角」は、検索や比較を安定させるための前処理でした。
一方で「半角→全角」は、どちらかというと「見た目」と「フォーマット」をそろえるための技です。

帳票にきれいに印字したい。
画面上で桁をそろえたい。
外部システムとのインターフェース仕様が「全角英数字で送ること」になっている。

こういうときに、「半角で入ってきた文字を全角に変換してから扱う」ユーティリティがあると、とても便利です。

ここでは、C# 初心者向けに、半角→全角の基本的な考え方と、実務で使えるユーティリティの作り方を、例題付きで丁寧に解説していきます。


半角と全角の関係をざっくり押さえる

「見た目の幅」だけでなく「別の文字」として存在している

全角→半角のときと同じですが、まず大事なのは「半角と全角は別の文字」という事実です。

半角 A:'A'
全角A:'A'

見た目は似ていますが、Unicode 上では別のコードポイントです。
そのため、次のような比較は false になります。

string hankaku = "ABC123";
string zenkaku = "ABC123";

Console.WriteLine(hankaku == zenkaku); // false
C#

「半角で入ってきたものを、帳票や画面では全角でそろえたい」というときは、
この差を埋めるために「半角→全角変換」が必要になります。


一番分かりやすい方法 マッピングテーブルで 1 文字ずつ変換する

発想は「全角→半角」と同じ

やり方の基本は、全角→半角のときと同じです。

半角文字と全角文字の対応表(マッピング)を用意する。
文字列を 1 文字ずつ見て、マップに載っていれば全角に置き換える。
載っていなければ、そのまま残す。

これが一番シンプルで、「どの文字がどう変わるか」を完全に自分でコントロールできます。

コード例:半角英数字+一部記号を全角にする

using System;
using System.Collections.Generic;
using System.Text;

public static class HankakuConverter
{
    private static readonly Dictionary<char, char> HankakuToZenkakuMap = new()
    {
        ['0'] = '0', ['1'] = '1', ['2'] = '2', ['3'] = '3', ['4'] = '4',
        ['5'] = '5', ['6'] = '6', ['7'] = '7', ['8'] = '8', ['9'] = '9',

        ['A'] = 'A', ['B'] = 'B', ['C'] = 'C', ['D'] = 'D', ['E'] = 'E',
        ['F'] = 'F', ['G'] = 'G', ['H'] = 'H', ['I'] = 'I', ['J'] = 'J',
        ['K'] = 'K', ['L'] = 'L', ['M'] = 'M', ['N'] = 'N', ['O'] = 'O',
        ['P'] = 'P', ['Q'] = 'Q', ['R'] = 'R', ['S'] = 'S', ['T'] = 'T',
        ['U'] = 'U', ['V'] = 'V', ['W'] = 'W', ['X'] = 'X', ['Y'] = 'Y',
        ['Z'] = 'Z',

        ['a'] = 'a', ['b'] = 'b', ['c'] = 'c', ['d'] = 'd', ['e'] = 'e',
        ['f'] = 'f', ['g'] = 'g', ['h'] = 'h', ['i'] = 'i', ['j'] = 'j',
        ['k'] = 'k', ['l'] = 'l', ['m'] = 'm', ['n'] = 'n', ['o'] = 'o',
        ['p'] = 'p', ['q'] = 'q', ['r'] = 'r', ['s'] = 's', ['t'] = 't',
        ['u'] = 'u', ['v'] = 'v', ['w'] = 'w', ['x'] = 'x', ['y'] = 'y',
        ['z'] = 'z',

        ['!'] = '!', ['@'] = '@', ['#'] = '#', ['$'] = '$', ['%'] = '%',
        ['^'] = '^', ['&'] = '&', ['*'] = '*', ['('] = '(', [')'] = ')',
        ['-'] = '-', ['_'] = '_', ['='] = '=', ['+'] = '+',
        ['['] = '[', [']'] = ']', ['{'] = '{', ['}'] = '}',
        [';'] = ';', [':'] = ':', ['\''] = ''', ['"'] = '"',
        [','] = ',', ['.'] = '.', ['/'] = '/', ['?'] = '?',
        ['<'] = '<', ['>'] = '>', ['|'] = '|', ['\\'] = '\',
        [' '] = ' ' // 半角スペース→全角スペース
    };

    public static string ToZenkakuBasic(string? input)
    {
        if (string.IsNullOrEmpty(input))
        {
            return string.Empty;
        }

        var sb = new StringBuilder(input.Length);

        foreach (char c in input)
        {
            if (HankakuToZenkakuMap.TryGetValue(c, out char mapped))
            {
                sb.Append(mapped);
            }
            else
            {
                sb.Append(c);
            }
        }

        return sb.ToString();
    }
}
C#

使い方の例

string raw = "ID: ABC123 @test";

string zenkaku = HankakuConverter.ToZenkakuBasic(raw);

Console.WriteLine(raw);    // ID: ABC123 @test
Console.WriteLine(zenkaku); // ID: ABC123 @test
C#

ここでのポイントはこうです。

英数字と記号だけを全角にしているので、日本語(漢字・ひらがな・カタカナ)はそのまま残る。
半角スペースを全角スペースに変えているので、帳票などで桁をそろえやすくなる。
どの文字がどう変わるかがコード上で明示されているので、仕様としても分かりやすい。

「帳票用に“英数字は全部全角で”」といった要件には、このくらいのユーティリティがちょうどいいです。


null 安全な半角→全角

null をそのまま通すと落ちる

さっきの ToZenkakuBasic は、string.IsNullOrEmpty で null と空文字をまとめて空文字にしています。
これにより、「null が来ても例外にならない」ようにしています。

もし、null を null のまま扱いたい場合は、戻り値を string? にして、こう書き換えることもできます。

public static string? ToZenkakuOrNull(string? input)
{
    if (input is null)
    {
        return null;
    }

    return ToZenkakuBasic(input);
}
C#

どちらの方針を取るかは、「システム全体で null をどう扱うか」によります。
多くの業務システムでは、「文字列は基本的に空文字にそろえる」ほうが扱いやすいので、
最初の string.Empty にそろえる形を採用することが多いです。


カナ(カタカナ)をどうするか問題

半角カナ→全角カナは少し難易度が上がる

日本語特有のややこしさとして、「半角カナ」があります。

例えば、カタカナカタカナ にしたい、というパターンです。
これは、単純に 1 文字→1 文字ではなく、「濁点・半濁点」との組み合わせも絡んできます。

ガ は「カ」+「゙」
パ は「ハ」+「゚」

これを「ガ」「パ」に変換するには、2 文字を 1 文字にマージする必要があります。

ここまでやろうとすると、マッピングテーブルもロジックも一気に複雑になるので、
初心者向けの段階では、まず「英数字+記号だけ全角にする」ユーティリティをしっかり押さえておくのがおすすめです。

カナまで含めた本格的な変換が必要になったら、そのときに専用ライブラリや、
もう少し高度な実装(2 文字を 1 文字にマージするロジック)を検討すれば十分です。


実務での使いどころと設計のポイント

帳票・画面表示で「見た目をそろえる」

半角→全角が一番活きるのは、「見た目をそろえたい場面」です。

固定長帳票で、桁をきっちり合わせたい。
画面上の一覧で、英数字も日本語も同じ幅で並べたい。
外部仕様書に「英数字は全角で」と書かれている。

こういうときは、出力直前の層で半角→全角をかけるのが定番です。

例えば、帳票出力用の DTO を組み立てるときに、こうします。

string rawName = customer.Name; // 内部では半角混じりでもよい

string printName = HankakuConverter.ToZenkakuBasic(rawName);
// ここから先は printName を帳票に流し込む
C#

内部ロジックでは「半角でも全角でもいい」状態で持っておき、
「出力のときだけ全角にそろえる」という分担にすると、柔軟で扱いやすくなります。

「どの項目に適用するか」を決めておく

全角→半角と同じく、半角→全角も「何でもかんでも変換すればいい」というものではありません。

メールアドレスや URL は、半角のまま扱うべきです。
コード値(ID)も、比較や検索のために半角にそろえておくことが多いです。
逆に、氏名や住所、帳票に出すラベルなどは全角にそろえたほうが見やすいことが多いです。

つまり、

入力時(検索キーなど)は全角→半角でそろえる。
出力時(帳票・画面表示など)は半角→全角でそろえる。

というように、「場面ごとにどちらの方向に寄せるか」を決めておくと、設計がスッキリします。


まとめ 「半角→全角ユーティリティ」は“見た目と仕様を裏切らないための仕上げ”

半角→全角は、ロジックを変えるというより、「見た目」と「外部仕様」を守るための仕上げ処理です。

押さえておきたいポイントは次の通りです。

半角と全角は別文字なので、見た目をそろえたいときは変換が必要になる。
英数字+記号の半角→全角は、Dictionary<char, char> を使った 1 文字ずつのマッピングがシンプルで確実。
null 安全にするために、「null や空文字が来たら空文字を返す」ユーティリティにしておくと扱いやすい。
カナ(半角カナ→全角カナ)は一気に難易度が上がるので、まずは英数字+記号から押さえるのがおすすめ。
入力側では全角→半角、出力側では半角→全角、といったように、「どの層でどちらに寄せるか」を決めておくと、システム全体の整合性が取りやすい。

ここまで理解できれば、「なんとなく全角・半角が混ざっている」状態から抜け出して、
「どのタイミングで、どの方向に、どう変換するか」を意図してコントロールできる C# ユーティリティを書けるようになっていきます。

タイトルとURLをコピーしました