C#で文字列から数字だけを抽出する基本
C#で文字列から数字だけを抽出したい場面は、業務システムではとてもよくあります。たとえば、電話番号からハイフンを除いて数字だけにしたいとき、郵便番号入力から余計な記号を取り除きたいとき、商品コードの中から数値部分だけを取り出したいとき、あるいは帳票やCSV取込データを整形したいときなどです。見た目は単純な処理に見えますが、実務では「どの数字を対象にするのか」「何を捨てて何を残すのか」「空文字や null をどう扱うのか」といった設計判断が必要になります。
初心者の方が最初に理解しておきたいのは、「数字だけ抽出する」という処理は、ただ文字を消すだけではなく、入力値を業務で使いやすい形に正規化する処理だということです。つまり、単なるテクニックではなく、入力品質や検索精度、外部連携の安定性に関わる重要な前処理です。だからこそ、動けばよいではなく、安全に、意図が分かる形で実装することが大切です。
C#では、この処理を実現する方法はいくつかあります。代表的なのは次の方法です。
char.IsDigit()を使って1文字ずつ判定する方法LINQを使って簡潔に書く方法Regexを使って不要な文字をまとめて除去する方法
初心者の方には、まず char.IsDigit() を使った方法から理解するのがおすすめです。なぜなら、どの文字を見て、どの文字を残しているのかが分かりやすく、文字列処理の基礎力が身につくからです。そこから、必要に応じて Regex や共通化へ進むのが実務的です。
まず理解したい「数字だけ抽出する」とは何か
「数字だけ抽出する」とは、文字列の中に含まれている文字を1つずつ確認して、その中で数字だけを残し、それ以外を除外することです。たとえば、次のような文字列があったとします。
ABC123DEF03-1234-5678〒150-0001
これらから数字だけを取り出すと、結果は次のようになります。
ABC123DEF→12303-1234-5678→0312345678〒150-0001→1500001
この処理は、電話番号や郵便番号の正規化では非常に便利です。ただし、ここで大切なのは「数字以外をすべて消してよいのか」を考えることです。たとえば、金額文字列から小数点も残したい場合や、マイナス記号を残したい場合には、「数字だけ抽出する」処理では要件を満たせません。つまり、処理を始める前に、対象データの意味を理解することが大切です。
最初に覚えたい `char.IsDigit()` を使う方法
初心者の方に最もおすすめしやすいのが、1文字ずつ見て、数字だけを残す方法です。C#では、文字が数字かどうかを判定するために char.IsDigit() を使えます。
まずは基本のコードを見てみましょう。
using System;
using System.Text;
class Program
{
static void Main()
{
string input = "ABC123DEF";
StringBuilder numbersOnly = new StringBuilder();
// 文字列を1文字ずつ確認する
foreach (char c in input)
{
// 文字が数字なら追加する
if (char.IsDigit(c))
{
numbersOnly.Append(c);
}
}
Console.WriteLine("元の文字列: " + input);
Console.WriteLine("数字だけ抽出: " + numbersOnly.ToString());
}
}C#このコードでは、foreach を使って文字列を1文字ずつ取り出しています。そして、char.IsDigit(c) が true なら、その文字を StringBuilder に追加しています。最後に、集めた数字だけを文字列として取り出しています。
実行結果は次のようになります。
元の文字列: ABC123DEF
数字だけ抽出: 123C#この方法の良いところは、処理の流れが非常に分かりやすいことです。
- 1文字ずつ見る
- 数字かどうか判定する
- 数字なら残す
初心者の方は、まずこの流れを自分の言葉で説明できるようになると、文字列処理の理解が一気に深まります。
`StringBuilder` を使う理由も理解しておきましょう
上のコードでは、結果をためるのに StringBuilder を使っています。ここも初心者の方にとって大切なポイントです。
もし文字列連結を毎回 result += c; のように書いても、少量データなら動きます。ただし、文字列は変更不可なので、連結のたびに新しい文字列が作られます。そのため、文字数が多くなると無駄が増えやすくなります。StringBuilder は、こうした繰り返し連結を効率よく行うためのクラスです。
次のような書き方もできます。
using System;
class Program
{
static void Main()
{
string input = "ABC123DEF";
string result = "";
// 文字列連結で数字を追加する
foreach (char c in input)
{
if (char.IsDigit(c))
{
result += c;
}
}
Console.WriteLine(result);
}
}C#このコードも動きますが、実務では繰り返し処理の中での文字列連結は避けたいことが多いです。初心者のうちから、「繰り返しで文字をためるなら StringBuilder も選択肢に入る」と覚えておくと、後々役立ちます。
まずは簡単な例題で慣れましょう
ここでは、実務でよくある形をイメージしながら、段階的に例題を見ていきます。
例題1: 電話番号から数字だけを取り出す
電話番号入力では、利用者がハイフン付きで入力することがよくあります。そのままでも表示には問題ありませんが、内部保存や比較では数字だけにしたいことがあります。
このようにすれば、03-1234-5678 から 0312345678 を取り出せます。電話番号検索や重複チェックの前処理としてよく使われます。
using System;
using System.Text;
class Program
{
static void Main()
{
string phoneNumber = "03-1234-5678";
StringBuilder digits = new StringBuilder();
// 1文字ずつ確認して数字だけ取り出す
foreach (char c in phoneNumber)
{
if (char.IsDigit(c))
{
digits.Append(c);
}
}
Console.WriteLine("入力値: " + phoneNumber);
Console.WriteLine("数字のみ: " + digits.ToString());
}
}C#例題2: 郵便番号から記号を除いて整形する
郵便番号も、ハイフン付きとハイフンなしが混在しやすい項目です。
using System;
using System.Text;
class Program
{
static void Main()
{
string zipCode = "150-0001";
StringBuilder digits = new StringBuilder();
// 郵便番号から数字だけを抽出する
foreach (char c in zipCode)
{
if (char.IsDigit(c))
{
digits.Append(c);
}
}
Console.WriteLine("入力値: " + zipCode);
Console.WriteLine("整形後: " + digits.ToString());
}
}C#このような処理は、外部API連携や検索キー作成でもよく使います。
`null` と空文字の扱いはとても重要です
ここは実務上かなり重要です。初心者の方は、最初は「きれいな入力値」だけで考えがちですが、実務ではそうはいきません。画面入力、CSV取込、データベース、APIレスポンスなどでは、値が入っていないことが普通にあります。
たとえば、次のようなコードは危険です。
using System;
using System.Text;
class Program
{
static void Main()
{
string input = null;
StringBuilder digits = new StringBuilder();
// inputがnullだとforeachでエラーになる
foreach (char c in input)
{
if (char.IsDigit(c))
{
digits.Append(c);
}
}
Console.WriteLine(digits.ToString());
}
}C#このコードでは、input が null のときにエラーになります。つまり、「文字列が必ず入っている」という前提で書いてはいけません。
安全な書き方1: 事前に `null` を確認する
using System;
using System.Text;
class Program
{
static void Main()
{
string input = null;
if (input == null)
{
Console.WriteLine("入力値がありません。");
return;
}
StringBuilder digits = new StringBuilder();
// nullでないことが分かってから処理する
foreach (char c in input)
{
if (char.IsDigit(c))
{
digits.Append(c);
}
}
Console.WriteLine(digits.ToString());
}
}C#この書き方はとても基本ですが、安全です。
安全な書き方2: ユーティリティメソッドにまとめる
実務では、毎回同じチェックを書くより、共通メソッドにしたほうが使いやすいです。
using System;
using System.Text;
public static class StringUtility
{
// 文字列から数字だけを抽出する
public static string ExtractDigits(string input)
{
// nullまたは空文字なら空文字を返す
if (string.IsNullOrEmpty(input))
{
return string.Empty;
}
StringBuilder digits = new StringBuilder();
// 1文字ずつ確認して数字だけ追加する
foreach (char c in input)
{
if (char.IsDigit(c))
{
digits.Append(c);
}
}
return digits.ToString();
}
}
class Program
{
static void Main()
{
string value = "TEL: 03-1234-5678";
string result = StringUtility.ExtractDigits(value);
Console.WriteLine(result);
}
}C#このようにしておくと、どこからでも安全に再利用しやすくなります。
LINQを使うと短く書けます
C#に少し慣れてきたら、LINQを使う方法も理解しておくと便利です。コードを短く書けるからです。
using System;
using System.Linq;
class Program
{
static void Main()
{
string input = "ABC123DEF";
// 数字だけを抽出して新しい文字列にする
string digits = new string(input.Where(char.IsDigit).ToArray());
Console.WriteLine("元の文字列: " + input);
Console.WriteLine("数字のみ: " + digits);
}
}C#これはとてもコンパクトですが、初心者の方にとっては少し抽象的に見えるかもしれません。何をしているかを分解すると、次の流れです。
Where(char.IsDigit)で数字だけを選ぶToArray()で文字配列にするnew string(...)で文字列に戻す
短く書けるのは魅力ですが、最初は foreach 版を理解してから使うほうが安心です。
`Regex` を使う方法も実務でよく使います
数字以外をまとめて除去したい場合は、正規表現の Regex も便利です。
using System;
using System.Text.RegularExpressions;
class Program
{
static void Main()
{
string input = "TEL: 03-1234-5678";
// 数字以外の文字を空文字に置き換える
string digits = Regex.Replace(input, "[^0-9]", "");
Console.WriteLine("元の文字列: " + input);
Console.WriteLine("数字のみ: " + digits);
}
}C#このコードでは、[^0-9] が「0から9以外の文字」を意味しています。それを空文字に置き換えることで、数字だけが残ります。
これは実務でもよく使われますが、初心者の方にとっては記号の意味が分かりにくいことがあります。そのため、最初は「便利だけれど、意味を理解してから使う」と考えるのがおすすめです。
どの方法を選べばよいのか
ここは実務でとても大事です。数字だけ抽出する方法はいくつかありますが、常に同じ方法が正解とは限りません。目的によって使い分けます。
- 処理の流れを理解しやすくしたいなら
char.IsDigit()とforeach - 短く書きたいなら
LINQ - 不要文字を一気に除去したいなら
Regex
初心者向け、保守しやすさ重視なら、まずは foreach と char.IsDigit() を基本にするのがよいです。チーム開発では、「多少長くても意図がすぐ分かるコード」のほうが歓迎されることも多いです。
数字抽出で特に注意したい実務ポイント
ここは深掘りして理解しておきたい重要部分です。数字だけ抽出する処理は便利ですが、安易に使うと業務的に問題になることがあります。
負の数や小数を壊してしまう可能性がある
たとえば、-123.45 から数字だけを抽出すると、12345 になります。これは元の数値の意味を完全に変えてしまいます。つまり、金額、数量、割合などを扱う場面では、「数字だけ抽出する」が本当に正しいのかを確認しなければなりません。
全角数字の扱いを考える必要がある
char.IsDigit() は、半角数字だけでなく、全角数字も数字として判定します。たとえば、123 も数字として認識されます。これは便利でもありますが、結果として全角数字を含んだ文字列が返る可能性があります。
たとえば次のような入力です。
ABC123
この場合、抽出結果は 123 になります。もし半角数字としてそろえたいなら、数字抽出の前後で半角変換も検討する必要があります。
桁数チェックは別で必要になることが多い
電話番号や郵便番号では、数字だけ抽出したあとに桁数が正しいかを確認することがよくあります。数字だけ取り出せたから終わり、ではないことが多いです。
- 郵便番号なら7桁か
- 電話番号なら10桁または11桁か
- 社員番号なら固定長か
つまり、数字抽出はあくまで前処理であり、その後にバリデーションが必要なことが多いです。
業務で使いやすいユーティリティメソッドにまとめる
実務では、同じ処理を何度も書かないように共通化するのが基本です。ここでは、使いやすいテンプレートを紹介します。
シンプルな数字抽出ユーティリティ
using System.Text;
public static class StringUtility
{
// 文字列から数字だけを抽出する
public static string ExtractDigits(string input)
{
// nullまたは空文字なら空文字を返す
if (string.IsNullOrEmpty(input))
{
return string.Empty;
}
StringBuilder digits = new StringBuilder();
// 数字だけを順番に追加する
foreach (char c in input)
{
if (char.IsDigit(c))
{
digits.Append(c);
}
}
return digits.ToString();
}
}C#前後空白を考慮するテンプレート
using System.Text;
public static class StringUtility
{
<em>// 入力値を整えてから数字だけを抽出する</em>
public static string ExtractDigitsNormalized(string input)
{
<em>// nullまたは空白だけなら空文字を返す</em>
if (string.IsNullOrWhiteSpace(input))
{
return string.Empty;
}
<em>// 前後の空白を削除する</em>
input = input.Trim();
StringBuilder digits = new StringBuilder();
<em>// 数字だけを取り出す</em>
foreach (char c in input)
{
if (char.IsDigit(c))
{
digits.Append(c);
}
}
return digits.ToString();
}
}C#郵便番号や電話番号向けのチェック付きテンプレート
using System.Text;
public static class StringUtility
{
// 郵便番号向けに数字だけ抽出する
public static string NormalizeZipCode(string input)
{
// まず数字だけ取り出す
string digits = ExtractDigits(input);
// 郵便番号は7桁を想定する
if (digits.Length != 7)
{
return string.Empty;
}
return digits;
}
// 共通の数字抽出処理
private static string ExtractDigits(string input)
{
// nullまたは空白だけなら空文字を返す
if (string.IsNullOrWhiteSpace(input))
{
return string.Empty;
}
StringBuilder digits = new StringBuilder();
// 数字だけを追加する
foreach (char c in input)
{
if (char.IsDigit(c))
{
digits.Append(c);
}
}
return digits.ToString();
}
}C#このようにしておくと、「ただ数字を抜き出す」だけでなく、「業務で使える形に整える」ところまで一貫して扱いやすくなります。
パフォーマンスの考え方も少し知っておきましょう
初心者のうちは、まず正しく動くことを優先して問題ありません。ただし、実務では大量データ処理を行うこともあるため、文字列処理のコストも少し意識するとよいです。
たとえば、ループの中で毎回文字列連結をすると、無駄な文字列生成が増えます。そのため、繰り返し追加するなら StringBuilder が向いています。また、同じ入力に対して何度も抽出処理を実行するのではなく、一度結果を変数に入れて使い回すことも大切です。
悪い例です。
using System;
using System.Text;
class Program
{
static void Main()
{
string input = "TEL: 03-1234-5678";
// 同じ処理を何度も呼んでいる
Console.WriteLine(ExtractDigits(input));
Console.WriteLine(ExtractDigits(input));
}
static string ExtractDigits(string input)
{
StringBuilder digits = new StringBuilder();
foreach (char c in input)
{
if (char.IsDigit(c))
{
digits.Append(c);
}
}
return digits.ToString();
}
}C#改善例です。
using System;
using System.Text;
class Program
{
static void Main()
{
string input = "TEL: 03-1234-5678";
// 一度だけ抽出して結果を使い回す
string digits = ExtractDigits(input);
Console.WriteLine(digits);
Console.WriteLine(digits);
}
static string ExtractDigits(string input)
{
StringBuilder digitsBuilder = new StringBuilder();
foreach (char c in input)
{
if (char.IsDigit(c))
{
digitsBuilder.Append(c);
}
}
return digitsBuilder.ToString();
}
}C#このように、無駄な再計算を避けるだけでも、コードの見通しがよくなります。
セキュリティと品質の観点でも大切です
数字だけ抽出する処理は、入力値の揺れを抑えるうえで有効です。ただし、元の値をそのまま保持すべきケースもあります。たとえば、監査ログ、申込原文、ユーザー入力の証跡などは、加工前の値も必要になることがあります。
そのため、実務では次のように考えるのが安全です。
- 元の入力値はそのまま保持する
- 検索用・比較用として数字抽出後の値を別に持つ
- どのタイミングで正規化するかを設計で決める
また、数字だけ抽出した結果をそのまま信頼してはいけない場面もあります。たとえば、電話番号らしく見えても桁数が違えば不正な値かもしれません。つまり、抽出は前処理であり、検証は別途必要です。
よくある失敗と注意点
数字だけ取り出せば必ず正しい値になると思い込む
これは危険です。数字だけになっても、その値が業務的に正しいとは限りません。桁数、形式、存在確認などは別途必要です。
`null` や空文字を考慮しない
実務では必ず出てきます。例外を防ぐためにも、早い段階で安全な共通処理にまとめるのがおすすめです。
小数点やマイナス記号を勝手に消してしまう
数値っぽいからといって何でも数字抽出してしまうと、意味が変わることがあります。対象データの意味を理解してから使いましょう。
全角数字が残ることを見落とす
char.IsDigit() は全角数字も拾います。必要に応じて半角統一も考えましょう。
まとめ
C#で文字列から数字だけを抽出する処理は、電話番号、郵便番号、コード値、CSV取込、外部連携など、実務で非常によく使います。初心者の方は、まず char.IsDigit() を使って1文字ずつ判定する方法から理解するのがおすすめです。この方法は処理の流れが分かりやすく、基礎力が身につきやすいからです。
特に重要なのは次の点です。
- 数字抽出は単なる文字削除ではなく、正規化処理であること
nullや空文字を安全に扱うこと- 必要に応じて桁数チェックや形式チェックを組み合わせること
- 小数点やマイナス記号を含む値には安易に使わないこと
- 全角数字が混ざる可能性も意識すること
- よく使う処理はユーティリティ化して再利用すること
初心者の方は、まず「どうやって数字だけを残すか」だけでなく、「なぜその処理をするのか」「その後に何を検証すべきか」まで意識できるようになると、実務で通用するコードに近づきます。数字抽出は小さな処理に見えて、入力品質、検索精度、外部連携の安定性に大きく関わる重要な基礎です。
