C# Tips | 文字列処理:英字のみ抽出

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

はじめに 「英字のみ抽出」は“コードやIDからアルファベットの芯だけを抜き出す”技

業務システムでは、こんな文字列がよく出てきます。

"UserID: AB123"
"商品コード: JP-2025-001"
"Server01-US-East"

人間なら「英字の部分はここだな」とすぐ分かりますが、
プログラムにとっては、数字・記号・英字がごちゃ混ぜの「ただの文字列」です。

ここで欲しいのは、

「文字列の中から“英字だけ”を取り出す、小さくて頼れるユーティリティ」

です。

ここでは、初心者向けに、

英字だけを抜き出す基本パターン(ループ/LINQ)
正規表現で「英字の塊ごと」に抜き出す方法
大文字・小文字をどう扱うか
null や空文字に強いユーティリティ化

を、例題付きでかみ砕いて説明していきます。


全体の考え方 「何を英字とみなすか」を最初に決める

英字抽出で最初に決めておきたいのは、

「A〜Z と a〜z だけを対象にするのか?」
「全角アルファベット(A〜Z)も含めるのか?」

という方針です。

ここでは、まずは一番シンプルに、

「半角の英字(A〜Z, a〜z)のみを対象」

として話を進めます。
必要になったら、「全角も含める」バージョンに拡張するイメージを持っておくとよいです。


1. ループで“英字だけを拾い集める”シンプル実装

char.IsLetter ではなく「英字だけ」に絞る理由

C# には char.IsLetter という「文字かどうか」を判定するメソッドがありますが、
これは「日本語のひらがな・カタカナ・漢字」も true になります。

英字だけに絞りたいので、ここでは

(c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')

という判定を自前で書きます。

一番分かりやすい実装

using System;
using System.Text;

public static class AlphaExtractor
{
    public static string ExtractAlphabet(string? value)
    {
        if (string.IsNullOrEmpty(value))
        {
            return string.Empty;
        }

        var sb = new StringBuilder(value.Length);

        foreach (char c in value)
        {
            if (IsAsciiLetter(c))
            {
                sb.Append(c);
            }
        }

        return sb.ToString();
    }

    private static bool IsAsciiLetter(char c)
    {
        return (c >= 'A' && c <= 'Z') ||
               (c >= 'a' && c <= 'z');
    }
}
C#

ここでやっていることはシンプルです。

null や空文字なら空文字を返す。
1 文字ずつ見て、「A〜Z または a〜z」なら StringBuilder に追加。
最後に ToString() で文字列に戻す。

動作例でイメージを固める

Console.WriteLine(AlphaExtractor.ExtractAlphabet("UserID: AB123"));        // UserIDAB
Console.WriteLine(AlphaExtractor.ExtractAlphabet("商品コード: JP-2025-001")); // JP
Console.WriteLine(AlphaExtractor.ExtractAlphabet("Server01-US-East"));     // ServerUSEast
Console.WriteLine(AlphaExtractor.ExtractAlphabet("123-456"));              // 空文字
Console.WriteLine(AlphaExtractor.ExtractAlphabet(null));                   // 空文字
C#

ポイントは、「英字がどこに散らばっていても、とにかく全部くっつけて返す」という挙動です。

"Server01-US-East""ServerUSEast" のように、
数字やハイフンは全部落ちて、英字だけがつながります。


2. LINQ を使った“短く書ける版”

Where+ToArray で一行にまとめる

同じことを LINQ で書くと、かなりコンパクトになります。

using System;
using System.Linq;

public static class AlphaExtractorLinq
{
    public static string ExtractAlphabet(string? value)
    {
        if (string.IsNullOrEmpty(value))
        {
            return string.Empty;
        }

        return new string(value.Where(IsAsciiLetter).ToArray());
    }

    private static bool IsAsciiLetter(char c)
    {
        return (c >= 'A' && c <= 'Z') ||
               (c >= 'a' && c <= 'z');
    }
}
C#

value.Where(IsAsciiLetter) で「英字だけ」をフィルタし、
ToArray()char[] にしてから new string(...) で文字列にしています。

動作はループ版と同じ

Console.WriteLine(AlphaExtractorLinq.ExtractAlphabet("UserID: AB123"));    // UserIDAB
Console.WriteLine(AlphaExtractorLinq.ExtractAlphabet("Server01-US-East")); // ServerUSEast
C#

「英字だけ全部くっつける」という挙動は、ループ版と完全に同じです。
LINQ に慣れてきたら、この書き方のほうが「何をしているか」が一目で伝わりやすくなります。


3. 正規表現で「英字の塊ごと」に抜き出す

Regex.Matches で“英字の塊”を全部取る

今までは「英字だけ全部くっつける」でしたが、
「英字の塊ごとに欲しい」こともあります。

例えば、"Server01-US-East" から ["Server", "US", "East"] のように取りたい場合です。

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

public static class AlphaGroupExtractor
{
    public static string[] ExtractAlphaGroups(string? value)
    {
        if (string.IsNullOrEmpty(value))
        {
            return Array.Empty<string>();
        }

        var list = new List<string>();

        MatchCollection matches = Regex.Matches(value, @"[A-Za-z]+");

        foreach (Match m in matches)
        {
            if (m.Success)
            {
                list.Add(m.Value);
            }
        }

        return list.ToArray();
    }
}
C#

[A-Za-z]+ は「英字が 1 文字以上続く塊」にマッチする正規表現です。
Regex.Matches は、その塊を全部返してくれます。

動作例で「塊ごと」と「全部くっつける」の違いを確認する

void Dump(string label, string? value)
{
    Console.WriteLine($"[{label}]");
    foreach (var x in AlphaGroupExtractor.ExtractAlphaGroups(value))
    {
        Console.WriteLine($"  -> {x}");
    }
}

Dump("Server01-US-East", "Server01-US-East");
//  -> Server
//  -> US
//  -> East

Dump("商品コード: JP-2025-001", "商品コード: JP-2025-001");
//  -> JP

Dump("123-456", "123-456");
// (何も出ない)
C#

「英字の塊ごとに配列で欲しい」のか、
「英字だけ全部くっつけた 1 本の文字列が欲しい」のかで、
使うユーティリティを使い分けるイメージです。


4. 大文字・小文字をどう扱うかを決める

抽出後に「全部大文字」「全部小文字」にそろえる

英字だけを抜き出したあと、
「大文字・小文字をそろえて比較したい」「コードとして統一したい」ことがよくあります。

例えば、「英字だけ抜き出して、全部大文字にする」ユーティリティはこう書けます。

public static class AlphaNormalizeUtil
{
    public static string ExtractAlphabetUpper(string? value)
    {
        string alpha = AlphaExtractor.ExtractAlphabet(value);
        return alpha.ToUpperInvariant();
    }

    public static string ExtractAlphabetLower(string? value)
    {
        string alpha = AlphaExtractor.ExtractAlphabet(value);
        return alpha.ToLowerInvariant();
    }
}
C#

動作例です。

Console.WriteLine(AlphaNormalizeUtil.ExtractAlphabetUpper("UserId: ab123")); // USERIDAB
Console.WriteLine(AlphaNormalizeUtil.ExtractAlphabetLower("UserID: AB123")); // useridab
C#

「抽出」と「正規化(大文字・小文字統一)」を分けておくと、
用途に応じて組み合わせやすくなります。


5. 全角アルファベットも含めたい場合の考え方

char.IsLetter を使うと“日本語も含まれてしまう”問題

「ABC」などの全角アルファベットも対象にしたい場合、
char.IsLetter を使えば一見うまくいきそうですが、
これは「ひらがな・カタカナ・漢字」も true になってしまいます。

例えば、

foreach (char c in "ABCあいう")
{
    Console.WriteLine($"{c}: {char.IsLetter(c)}");
}
C#

のようにすると、全角英字も日本語も全部 true になります。

実務では「まず半角だけ」で割り切るのもアリ

全角アルファベットまできちんと扱おうとすると、
「Unicode カテゴリ」を意識したり、
「全角→半角変換」と組み合わせたりする必要が出てきます。

業務でよくあるのは、

「入力は基本的に半角英数字でお願いしている」
「もし全角が来たら、別のバリデーションで弾く」

という運用です。

なので、英字抽出ユーティリティとしては、

「まずは半角英字だけを対象にする」
「全角をどうするかは、別のレイヤー(入力チェック)で決める」

という割り切りも、十分現実的です。


6. 実務での設計ポイント 「何に使うか」から逆算する

英字のみ抽出ユーティリティを設計するときは、
「どんな場面で使うか」から逆算するとブレません。

例えば、

商品コードから「国コード(JP, US など)だけ取りたい」
サーバー名から「リージョンコード(USEast など)だけ取りたい」
ログの中から「英字だけの識別子」を拾いたい

といった用途なら、

英字だけ全部くっつける ExtractAlphabet
英字の塊ごとに配列で取る ExtractAlphaGroups
大文字・小文字をそろえる ExtractAlphabetUpper/Lower

を組み合わせるだけで、かなりのケースをカバーできます。

「どの粒度で欲しいか」(1 本の文字列か、塊ごとの配列か)
「大文字・小文字をそろえるか」
「null や空文字のときどうするか」

このあたりを最初に決めて、ユーティリティに“ルールとして埋め込む”のがポイントです。


まとめ 「英字のみ抽出ユーティリティ」は“文字列からアルファベット情報だけを救い出すフィルタ”

英字のみ抽出は、見た目はシンプルですが、

コードやIDから「アルファベット部分だけ」を取り出す
記号や数字を落として、英字だけで比較・検索したい
ログやテキストから、英字の識別子だけを拾いたい

といった場面で、じわじわ効いてくるユーティリティです。

押さえておきたいポイントは、

半角英字だけなら (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') で判定するのが分かりやすい。
「英字だけ全部くっつける」版と、「英字の塊ごとに配列で取る」版を使い分ける。
抽出後に ToUpperInvariantToLowerInvariant で大文字・小文字をそろえると、比較や検索がしやすくなる。
null や空文字は「空文字/空配列を返す」ルールにしておくと、呼び出し側の if が減る。

ここまで理解できれば、「なんとなく英字を抜いている」段階から一歩進んで、
“文字列からアルファベット情報だけを救い出すフィルタ”として、
業務で使える C# の英字抽出ユーティリティを、自分の手で設計・実装できるようになっていきます。

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