ホームに戻る
出典 :
関連 :
目次 :
.NETにおける正規表現
System.Text.RegularExpressions.Regex
クラスには正規表現の機能が実装されており、静的メソッドとしてアクセスが可能である。
(インスタンスを生成することも可能で、その場合はパターンなどを保持する。詳細は割愛。)
Match() : パターンにマッチする箇所
入力文字列における、パターンにマッチする箇所の情報(System.Text.RegularExpressions.Match
)を返す。
記述例
using System.Text.RegularExpressions;
:
string input = "0120-444-444"; //< 入力文字列
string pattern = @"\d+" //< 検索パターン
// input 中の pattern にマッチする箇所を取得
Match match = Regex.Match( input, pattern );
// マッチする箇所が存在する場合、その情報を順に出力する
while( m.Success )
{
Console.WriteLine( $@"{m.Index} 文字目に ""{m.Value}"" が見つかりました。" );
m = m.NextMatch();
}
出力結果
0 文字目に "0120" が見つかりました。
5 文字目に "444" が見つかりました。
9 文字目に "444" が見つかりました。
キャプチャ結果の取得
添字付きプロパティ Match.Groups[]
を用いることで、番号または名前を指定してキャプチャ結果を参照できる。
キャプチャ結果の文字列は Value
プロパティで取得できる。
記述例
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
// 入力文字列
string input = "The cow jumped over the moon.";
// 検索パターン
// | \1 |
// | |
string pattern = @"\b(?<FirstWord>\w+)\s?((\w+)\s)*(?<LastWord>\w+)?";
// | | | | | |
// |<- FirstWord ->| | \2| |<- LastWord ->|
// マッチ結果取得
// 成功時はキャプチャ結果を出力
Match match = Regex.Match( input, pattern );
if (match.Success)
{
Console.WriteLine( $@"1 : '{match.Groups[1].Value}'" );
Console.WriteLine( $@"2 : '{match.Groups[2].Value}'" );
Console.WriteLine( $@"FirstWord : '{match.Groups["FirstWord"].Value}'" );
Console.WriteLine( $@"LastWord : '{match.Groups["LastWord"].Value}'" );
}
}
}
出力結果
1 : 'the ' //< キャプチャ番号 1 ( \1 )
2 : 'the' //< キャプチャ番号 2 ( \2 )
FirstWord : 'The' //< 名前付きキャプチャ "FirstWord"
LastWord : 'moon' //< 名前付きキャプチャ "LastWord"
解説
上記のコードでは、通常のキャプチャと名前付きキャプチャを同時に行っている。
注意が必要な点として、割り当てられるキャプチャ番号は名前無し⇒名前付きの順となる。
(最も左にある "FirstWord" は名前付きのためスキップされ、名前無しのキャプチャに番号 1 が割り当てられる。
ちなみに番号 0 はキャプチャではなく、パターン全体のマッチ結果となる。)
Matches() : パターンにマッチする箇所の一覧
入力文字列における、パターンにマッチするすべての箇所の情報( System.Text.RegularExpressions.MatchCollection
)を返す。
MatchCollection
はMatch
の集合で、foreach
で走査できる。
記述例
using System.Text.RegularExpressions;
:
string input = "0120-444-444"; //< 入力文字列
string pattern = @"\d+" //< 検索パターン
// input 中の pattern にマッチする箇所を取得
MatchCollection matches = Regex.Matches( input, pattern );
// マッチする箇所の情報を順に出力する
foreach( Match m in matches )
{
Console.WriteLine( $@"{m.Index} 文字目に ""{m.Value}"" が見つかりました。" );
}
出力結果
0 文字目に "0120" が見つかりました。
5 文字目に "444" が見つかりました。
9 文字目に "444" が見つかりました。
IsMatch() : パターンにマッチするか
入力文字列にパターンにマッチする箇所が含まれるかを返す。
記述例
using System.Text.RegularExpressions;
:
string input = "0120-444-444"; //< 入力文字列
string pattern = @"\d+" //< 検索パターン
// input 中に pattern にマッチする箇所が存在するかを取得 ⇒ 存在するため true
bool isMatch = Regex.IsMatch( input, pattern );
Count() : パターンにマッチする数
入力文字列における、パターンにマッチする箇所の数を返す。
記述例
using System.Text.RegularExpressions;
:
string input = "0120-444-444"; //< 入力文字列
string pattern = @"\d+" //< 検索パターン
// input 中の pattern にマッチする個数を取得 ⇒ 3
int count = Regex.Count( input, pattern );
Replace() : パターンにマッチする箇所をすべて置換
入力文字列における、パターンにマッチする箇所すべてを指定された文字列で置換する。
記述例
using System.Text.RegularExpressions;
:
string input = "0120-444-444"; //< 入力文字列
string pattern = @"\d{3}"; //< 検索パターン
string replacement = "###"; //< 置換後文字列
// input 中の pattern にマッチする箇所を replacement で置換 ⇒ "0120-###-###"
string output = Regex.Replace( input, pattern, replacement );
キャプチャおよび名前付きキャプチャ
置換後文字列中でキャプチャを参照する場合は表記が異なる。
|
番号によるキャプチャ |
名前付きキャプチャ |
検索パターン中で参照(後方参照) |
\1, \2, ... |
\k<CaptureName> |
置換後文字列中で参照 |
$1, $2, ... |
${CaptureName} |
記述例
using System.Text.RegularExpressions;
:
string input = "Good morning. Good evening."; //< 入力文字列
string pattern = @"(Good) (\w+)\. \1 (\w+)\."; //< 検索パターン
string replacement = @"Bad $2. Bad $3."; //< 置換後文字列
// 検索パターンおよび置換後文字列でキャプチャ結果を参照
// "Good morning. Good evening." ⇒ "Bad morning. Bad evening."
string output = Regex.Replace( input, pattern, replacement );
解説
入力文字列 "Good morning. Good evening." を検索パターン "(Good) (\w+)\. \1 (\w+)\." で評価しており、
- キャプチャ 1 : Good
- キャプチャ 2 : morning
- キャプチャ 3 : evening
となる。
キャプチャ 1 は検索パターン中で参照するため\1
表記だが、キャプチャ 2 および 3 は置換後文字列中で参照するため$2
$3
表記となる。
GetGroupNames() : キャプチャしたグループ名をすべて取得
Match() でのキャプチャに使用した名称の一覧を返す。
記述例
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
// 入力文字列
string input = "The cow jumped over the moon.";
// 検索パターン
// | \1 |
// | |
string pattern = @"\b(?<FirstWord>\w+)\s?((\w+)\s)*(?<LastWord>\w+)?";
// | | | | | |
// |<- FirstWord ->| | \2| |<- LastWord ->|
// マッチする箇所を取得
// 成功時は内容を出力
Regex rgx = new Regex( pattern );
Match match = rgx.Match( input );
if (match.Success)
{
ShowMatches(rgx, match);
}
}
// マッチ結果の出力
private static void ShowMatches( Regex r, Match m )
{
// キャプチャグループ名の一覧を取得
string[] names = r.GetGroupNames();
Console.WriteLine("Named Groups:");
// キャプチャグループ名を走査
foreach (var name in names)
{
Group grp = m.Groups[name];
Console.WriteLine( $@" {name} : '{grp.Value}'" );
}
}
}
出力結果
Named Groups:
0 : 'The cow jumped over the moon.' //< パターン全体でのマッチ結果
1 : 'the ' //< キャプチャ番号 1 ( \1 )
2 : 'the' //< キャプチャ番号 2 ( \2 )
FirstWord : 'The' //< 名前付きキャプチャ "FirstWord"
LastWord : 'moon' //< 名前付きキャプチャ "LastWord"
解説
上記のコードでは、通常のキャプチャと名前付きキャプチャを同時に行っている。
キャプチャグループ名を取得するにはMatch()
を実行したRegEx
オブジェクトが必要となるため、Match()
実行前にインスタンスを作成している。
RegEx.GetGroupNames()
を実行すると名前付きキャプチャ("FirstWord"
および"LastWord"
)に加え、通常の(番号による)キャプチャ結果も返される。
(例えばキャプチャ番号 1 には名称 "1" が割り当てられる。Match.Groups[1]
とMatch.Groups["1"]
の結果は等しい。)
1 番目、2 番目のキャプチャは複数回実行(該当箇所が複数存在)され、結果は最新のもので上書きされる。
GetGroupNumbers() : キャプチャしたグループ番号をすべて取得
Match() でのキャプチャに使用した番号の一覧を返す。
記述例
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
// 入力文字列
string input = "The cow jumped over the moon.";
// 検索パターン
// | \1 |
// | |
string pattern = @"\b(?<FirstWord>\w+)\s?((\w+)\s)*(?<LastWord>\w+)?";
// | | | | | |
// |<- FirstWord ->| | \2| |<- LastWord ->|
// マッチする箇所を取得
// 成功時は内容を出力
Regex rgx = new Regex( pattern );
Match match = rgx.Match( input );
if (match.Success)
{
ShowMatches(rgx, match);
}
}
// マッチ結果の出力
private static void ShowMatches( Regex r, Match m )
{
// キャプチャグループ番号の一覧を取得
int[] numbers = r.GetGroupNumbers();
Console.WriteLine("Groups:");
// キャプチャグループ番号を走査
foreach (var number in numbers)
{
Group grp = m.Groups[number];
Console.WriteLine( $@" {number} : '{grp.Value}'" );
}
}
}
出力結果
Groups:
0 : 'The cow jumped over the moon.' //< パターン全体でのマッチ結果
1 : 'the ' //< キャプチャ番号 1 ( \1 )
2 : 'the' //< キャプチャ番号 2 ( \2 )
3 : 'The' //< 名前付きキャプチャ "FirstWord" ⇒ キャプチャ番号 3
4 : 'moon' //< 名前付きキャプチャ "LastWord" ⇒ キャプチャ番号 4
解説
キャプチャ番号を取得する際の手順はGetGroupNames()
と同様。名前付きキャプチャにも、通常のキャプチャに続く番号が割り当てられる。
Match.Groups[]
で結果を参照する際、名称(文字列)を用いるよりも番号(整数値)を用いるほうが高速であるため、特定の局面では有利にはたらく。
GroupNameFromNumber() : キャプチャグループ番号をグループ名に変換
キャプチャグループ番号から名称への変換を行う。
対応する変換結果が存在しない場合、String.Empty
を返す。
GroupNumberFromName() : キャプチャグループ名をグループ番号に変換
キャプチャグループ名称から番号への変換を行う。
対応する変換結果が存在しない場合、-1
を返す。