正規表現て何??
C#で正規表現を使うにはどうしたらいいの?
プログラムを実装していると、正規表現を扱う機会が少なからず一度は訪れることでしょう。
「正規表現」とは、文字列のパターンを意味したメタ文字と呼ばれる特別な文字と、通常の文字を組み合わせて、1つの文字列で表現したものです。
この正規表現を利用することで、任意の文字列を検索することや書き換えることなどができます。それも細かい条件をとても短い正規表現で書くことができるのが特徴です。
例えば、任意の文字列が全て数値であるかどうかを正規表現で確認するには、^\d+$
を使います。以下のように任意の文字列がとても長い場合でも、あっという間に判定ができてしまうのです。
正規表現^\d+$
を使えば、数値判定も楽々!
- 3141592653589793 ➡︎ 全て数値である
- 314159265A589793 ➡︎ 全て数値でない
メタ文字を使うと検索条件が短くなるメリットはありますが、初めてみる人にとってはどういう意味なのかとても分かりにくいというデメリットがあります。
この記事では、初めての方でも理解できるように正規表現で使われるメタ文字の一覧と意味の説明をし、C# で正規表現を扱う方法について解説をします。
慣れないと分かりにくいですが、1つ1つのメタ文字の意味は明確です。覚えてしまえば、いろんな条件の正規表現が作れるようになれます。
オススメの参考書
C#の使い方が丁寧に解説しており、「基礎からしっかりと学びたい」という初心者の方にオススメの一冊です。サンプルコードも記載してあり、各章の最後に復習問題があるので理解度を確認しながら読み進めることができます。新しい C# のバージョンにも対応している書籍です。
正規表現のメタ文字
正規表現は、通常の文字と次のようなメタ文字を使って表現されます。主なメタ文字の説明と使用例を表に記載しています。
メタ文字 | 説明 | 正規表現の例 | 一致する文字列の例 |
---|---|---|---|
^ | 行の先頭 | ^a | abc |
$ | 行の末尾 | $c | abc |
. | 任意の1文字 | . | a |
[] | カッコ内に含まれる任意の1文字と一致 | [abc] | a、b、cいずれか |
[^] | カッコ内に含まれる文字以外と一致 | [^abc] | a、b、c以外 |
* | 直前の文字を0回以上繰り返しと一致 | abc* | ab、abc… |
+ | 直前の文字を1回以上の繰り返しと一致 | abc+ | abc、abc… |
? | 直前の文字を0または1文字と一致 | abc? | abまたはabc |
+? | 直前の文字を1回以上繰り返しと一致 | abc+? | abc、abc… |
*? | 直前の文字を0回以上の繰り返しと一致 | abc*? | ab、abc… |
{n} | 直前の文字の桁数を指定 | a{2} | aa |
{n,} | 直前の文字の最小桁数のみ指定 | a{2,} | aa、aa… |
{n,m} | 直前の文字の最小桁数と最大桁数を指定 | a{2,3} | aa、aaa |
| | いずれかの条件 (OR条件)に一致 | a|b | aまたはb |
\ | 直後の正規表現記号をエスケープ | a\\bc | a\bc |
^(キャレット)は行頭を表します。例えば、^apple
というパターンは、”apple”や”applewatch”という文字列にマッチします。”penapple”など先頭がappleから始まらない場合はマッチしません。
$は行末を表します。例えば、apple$
というパターンは、”penapple”という文字にマッチします。”applewatch”など行末がappleで終わらない場合はマッチしません。
[]は下表にあるように特定のパターンを作って使うことが可能です。
パターン | 説明 | 一致する文字列の例 |
---|---|---|
[0-9] | 0〜9の数値のいずれか | 0、1、2… |
[^0-9] | 0〜9の数値以外 | a、b、c… |
[A-Z] | A〜Zまでの大文字アルファベットのいずれか | A、B、C… |
[A-Za-z] | A〜Z、a〜zまでの大文字と小文字のアルファベットのいずれか | A、B、C…、a、b、c… |
[01][01] | 0と1の組み合わせ | 00、01、10、11 |
[A-Za-z][0-9] | アルファベット1文字と数値1文字 | A0 |
これらのメタ文字を組み合わせて使うことで、検索や置換を行うためのパターンを短く簡潔に表現することができるのです。
メタ文字は定義済みの正規表現があります。この正規表現を使うことで更に簡潔に表現することができます。
パターン | 説明 | 対応するパターン |
---|---|---|
\d | 0〜9の数値のいずれか | [0-9] |
\D | 0〜9の数値以外 | [^0-9] |
\w | アルファベット、アンダーバー、数値のいずれか | [A-Za-z_0-9] |
\W | アルファベット、アンダーバー、数値以外の文字 | [^A-Za-z_0-9] |
\s | 空白文字 | [ \t\f\r\n] |
\S | すべての非空白文字 | [^ \t\f\r\n] |
ここまで読んでいただければ、記事の冒頭で書いた正規表現の意味を理解できるようになります。^\d+$
を分解してみてみましょう。
- ^:文字の先頭
- ^\d:0〜9の数値が文字の先頭から始まる
- ^\d+?:0〜9の数値が文字の先頭から始まり、0〜9の数値を1回以上繰り返す = 全て数値である
このように正規表現を使うことで、任意の文字列がパターンにマッチするかしないかをチェックすることができます。
正規表現の確認ツールとして「正規表現チェッカー」がありますので、ツールを活用して意図したパターンになっているか確認してみましょう。
よく使う正規表現
お手軽に正規表現を使えるように、よく使用する正規表現をピックアップしています。
パターン | 説明 | 一致する文字列の例 |
---|---|---|
^\d+$ | 半角数字(0〜9のいずれか) | 0、1、2… |
^[a-zA-Z]+$ | 半角英字(a〜z、A〜Zのいずれか) | a、b…、A、B… |
^[ぁ-んー]+$ | 全角ひらがな | しーしゃーぷ |
^[ァ-ンヴー]+$ | 全角カタカナ | シーシャープ |
^[ァ-ン゙゚\-]+$ | 半角カタカナ | シーシャープ |
^(0\d*)$ | ゼロから始まる数字 | 012345 |
^([1-9]\d*)$ | ゼロ以外から始まる数字 | 12345 |
^\d{4}-\d{1,2}-\d{1,2}$ | 日付(YYYY-MM-DD) | 2021-04-21 |
\d+\.\d+\.\d+\.\d+ | IPアドレス | 192.168.1.1 |
^\d{3}-\d{4}$ | 郵便番号 | 000−0000 |
^https?:\/\/ | URL | https:// |
^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$ | Emailアドレス | sample@gmail.com |
^(070|080|090)-\d{4}-\d{4}$ | 携帯番号 | 070-0000-0000 |
C#で正規表現を使う
C# で正規表現を扱うには、Regex
クラスを使います。このクラスが定義されている名前空間をusing
ディレクティブで指定します。
using System.Text.RegularExpressions;
まずは基本となる、パターンに一致することを判定する方法についてです。
パターンに一致するか判定
パターンに一致することを判定するにはIsMatch
メソッドを使います。
IsMatch
メソッドは第1引数に検索対象の文字列を指定し、第2引数に正規表現のパターンを指定します。
サンプルとして検索対象の文字列が数値であるか確認する処理を以下に記載しています。
var str = "1234567890";
var result = Regex.IsMatch(str, @"^\d+$");
if (result)
{
Console.WriteLine("パターンが一致しました。");
}
else
{
Console.WriteLine("パターンが一致しませんでした。");
}
str = "ABC1234567890";
result = Regex.IsMatch(str, @"^\d+$");
if (result)
{
Console.WriteLine("パターンが一致しました。");
}
else
{
Console.WriteLine("パターンが一致しませんでした。");
}
実行すると結果は次のようになります。
パターンが一致しました。
パターンが一致しませんでした。
最初に一致したパターンの部分を抽出
最初に一致したパターンの部分を抽出するには、Match
メソッドを使います。
Match
メソッドは第1引数に検索対象の文字列を指定し、第2引数に正規表現のパターンを指定します。
アルファベットと数値の組み合わせのパターンで、最初に一致した文字列を抽出するサンプルとアルファベットが続いているパターンで、最初に一致した文字列を抽出するサンプルを以下に記載しています。
var str = "ABC123DEF456GHI";
var match = Regex.Match(str, @"[A-Za-z][0-9]");
Console.WriteLine(match.Value);
str = "ABC123DEF456GHI";
match = Regex.Match(str, @"[A-Za-z]*");
Console.WriteLine(match.Value);
実行すると結果は次のようになります。
C1
ABC
一致したパターンの全ての部分を抽出
一致したパターンの全ての部分を抽出するには、Matchs
メソッドを使います。
Matches
メソッドは第1引数に検索対象の文字列を指定し、第2引数に正規表現のパターンを指定します。
サンプルとして検索対象の文字列で、数値部分を抽出するサンプルを以下に記載しています。
var str = "ABC123DEF456GHI";
var matchs = Regex.Matches(str, @"\d");
//一致した文字列の表示
foreach (Match match in matchs)
{
Console.WriteLine(match.Value);
}
実行すると結果は次のようになります。
1
2
3
4
5
6
一致したパターンを置換
パターンに一致した文字列を任意の文字列に置換したい場合は、Replace
メソッドを使います。
Replace
メソッドは第1引数に検索対象の文字列を指定し、第2引数に置換後の文字列を指定します。
サンプルとして検索対象の文字列で、数値部分を”0”に置換するサンプルを以下に記載しています。
var str = "ABC123DEF456GHI";
var regex = new Regex(@"\d");
var result = regex.Replace(str, "0");
Console.WriteLine(result);
実行すると結果は次のようになります。
ABC000DEF000GHI
正規表現のパターンに一致する部分を全ての文字列が置換されました。
一致した文字列の一部だけを置換したい場合は、Replace
メソッドの第3引数に置換場所を指定します。
一致したパターンの2つ目まで置換することも可能です。
var str = "ABC123DEF456GHI";
var regex = new Regex(@"\d");
var result = regex.Replace(str, "0", 2);
Console.WriteLine(result);
実行すると結果は次のようになります。
ABC003DEF456GHI
一致したパターンで分割
指定したパターンに一致した文字列を区切り文字として分割したい場合は、Split
メソッドを使います。
Split
メソッドは第1引数に検索対象の文字列を指定します。
数値部分を区切り文字として分割するサンプルを以下に記載しています。
var str = "ABC1DEF2GHI";
var regex = new Regex(@"\d");
var result = regex.Split(str);
foreach (var s in result)
{
Console.WriteLine(s);
}
実行すると結果は次のようになります。
ABC
DEF
GHI
まとめ
正規表現で使われる符号の意味や C# で正規表現を扱う方法について説明をしました。
プログラムをする上で正規表現を使う機会がある場合は参考にしてみてください。
以上、最後まで読んでいただきありがとうございました。