「マイクロソフト系技術情報 Wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。
正規表現(regular expression)
正規表現のパターン マッチを使用すれば、例えば、次のような処理に利用可能である。
現在では、Perl、PHP、Java、JavaScript、.NET、Python、Rubyなど、
広く様々なランタイムに実装されており、テキスト エディタ、ワード プロセッサをはじめとする、
アプリケーション ソフトの検索・置換機能などで利用することもできるようになっている。
ただし、ソフトウェアによって「方言」や利用できない機能があるため、注意が必要である。
正規表現は、
組み合わせて表記される。
正規表現の書き方を習得するには、これらの要素を覚える必要がある。
特別な意味を持った記号。
以下が、.NET Frameworkの正規表現で使用できるメタ文字。
項番 | 区分 | メタ文字 | 説明 / 注釈 |
1 | 位置指定子 | 「 ^ 」、「 $ 」の両方を指定することで全文のマッチを強制できる。 エスケープ文字に含まれる位置指定子もある。 | |
1-1 | ^ | 文字列の先頭を表す(中間からのマッチを拒否) ※ 正規表現、部分式の先頭のものしかメタ文字として認識されない。 | |
1-2 | $ | 文字列の末尾を表す(中間からのマッチを拒否) ※正規表現、部分式の終端のものしかメタ文字として認識されない。 | |
2 | 代替構成体 | 詳細はxxx節を参照 | |
2-1 | | | 「|」 で区切られた文字列のいずれか。 通常、下記、5-2の丸括弧と併用するが、単独で利用することも可能。 | |
3 | 量指定子 | 正規表現での量指定子 http://msdn.microsoft.com/ja-jp/library/3206d374.aspx | |
3-1 | * | 前の文字列が 0 回以上連続にマッチする( = {0,})。 | |
3-2 | + | 前の文字列が 1 回以上連続にマッチする( = {1,})。 | |
3-3 | ? | 前の文字列が 0 or 1 回マッチする( = {0,1})。 | |
3-4 | {n} | 前の文字列がn回連続にマッチする。 | |
3-5 | {n,} | 前の文字列がn回以上連続にマッチする。 | |
3-6 | {n, m} | 前の文字列がn-m回連続にマッチする。 | |
3-7 | *? ,etc. | *、+、?、{ } の後に「 ? 」をつけて「最短マッチ」を表す。 | |
4 | 文字クラス | 正規表現での文字クラス http://msdn.microsoft.com/ja-jp/library/20bw873z.aspx | |
4-1 | . (ピリオド) | 改行(\n)以外の任意の1文字 | |
4-2 | [ ] (角括弧) | 下記、5-1に該当 | |
4-3 | \s | スペースやタブなどの空白文字 | |
4-4 | \S | \S以外([^\s]と同義) | |
4-5 | \d | 10進数([0-9]と同義) | |
4-6 | \D | \d以外([^\d]と同義) | |
4-7 | \w | 単語に使用される任意の文字 ([\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}\p{Pc}\p{Lm}]と同義) | |
4-8 | \W | \w以外([^\w]と同義) | |
5 | 括弧 | ||
5-1 | [ ] 角括弧 詳細は「角括弧による文字グループ」を参照。 | 下記の角括弧内に指定した文字にマッチする。 ・文字範囲(Unicodeの文字コード表)、 ・文字グループ 以下は、角括弧内でのみ使われる特殊なメタ文字である。 ・「 - 」:範囲指定 、例えば[a-z]で半角英小文字の文字グループを表す。 ・「 ^ 」:先頭で使われたとき、「含まれない」と条件を反転する。 | |
5-2 | ( ) 丸括弧 詳細は「丸括弧による構成体」を参照 | 丸括弧内に指定した文字、文字範囲、文字グループに完全にマッチする。 グループ化構成体、代替構成体、その他の構成体を構成する。 | |
6 | 日本語文字クラス(\p{xxxx}) | .NET TIPS 文字列のひらがな/カタカナをチェックするには? - C# - @IT http://www.atmarkit.co.jp/fdotnet/dotnettips/054iskana/iskana.html | |
6-1 | \p{IsHiragana?} | 平仮名 | |
6-2 | \p{IsKatakana?} | 片仮名 | |
6-3 | \p{IsCJKUnifiedIdeographs?} | 漢字 | |
6-4 | P{xxxx} | p{xxxx}以外 |
エスケープ文字 には次のようなものがある。
項番 | 区分 | 文字のエスケープ | 説明 / 注釈 |
1 | 位置指定子 | ||
1-1 | \b | ワードの境界(\w文字と\W文字の間)。 例えば「\bVB\b」で単語としての「VB」となる。 規定では日本語と英語の境界は「\b」に含まれない。 従って、「\bVB\b」という正規表現で、 「これは、VBです」という文字列中のVBを検索できない。 ただし、これについては、ECMAScriptオプションで動作を変更できる。 角括弧の中にある場合、置換パターンの場合は、下記、3-2を参照。 | |
1-2 | \B | \b以外 | |
1-3 | \A | MultiLine?オプションを無視した文字列の先頭 | |
1-4 | \z | MultiLine?オプションを無視した文字列の末尾 | |
1-5 | \Z | MultiLine?オプションを無視した文字列の末尾(または文字列の末尾の「\n」の前) | |
1-6 | \G | 前回の一致が終了した位置で一致する必要があることを指定する。 | |
2 | メタ文字のエスケープ | 単純に、前に¥記号を付与する。 | |
2-1 | \. | . | |
2-2 | \^ | ^ | |
2-3 | \$ | $ | |
2-4 | \* | * | |
2-5 | \+ | + | |
2-6 | \? | ? | |
2-7 | \[ | [ | |
2-8 | \] | ] | |
2-9 | \( | ( | |
2-10 | \| | | | |
2-11 | \) | ) | |
2-12 | \{ | { | |
2-13 | \} | } | |
2-14 | \\ | \ | |
3 | 制御文字 | 各種 制御文字を正規表現中の文字列で表す場合。 | |
3-1 | \a | ベル(アラーム)の\u0007 | |
3-2 | \b | 角括弧の中にある場合、置換パターンの場合は、\u0008 | |
3-3 | \t | タブの\u0009 | |
3-4 | \r | キャリッジ リターンの\u000D | |
3-5 | \v | 垂直タブの\u000B | |
3-6 | \f | フォーム フィードの\u000C | |
3-7 | \n | 改行文字の\u000A | |
3-8 | \e | エスケープ文字の\u001B | |
3-9 | \cC | ASCII 制御文字 と一致(\cC は Ctrl + C) http://ja.wikipedia.org/wiki/ASCII#ASCII.E5.88.B6.E5.BE.A1.E6.96.87.E5.AD.97 | |
4 | コードポイント | 各種 コードポイントを正規表現中の文字列で表す場合。 | |
4-1 | \040 | 8進数(3桁まで)で表されるASCII文字と一致 | |
4-2 | \x20 | 16進数(2桁)で表されるASCII文字と一致 | |
4-3 | \u0020 | 16進数(4桁)で表されるUnicode文字と一致 |
角括弧を使用した文字グループの定義には次のようなものがある。
※ 下記の、Chn(Ch1、Ch2、Ch3、Ch4など)は文字を表す。
xx_ChGroup?(Base_ChGroup?、Excluded_ChGroup?)は文字グループを表す。
[Ch1Ch2]
[Ch1-Ch2]
[Ch1-Ch2Ch3-Ch4]
[Base_ChGroup?-[Excluded_ChGroup?]].etc
丸括弧を使用した
について説明する。
項番 | 区分 | グループ化構成 | 説明 | |
正規表現の例 | マッチする部分文字列 | |||
キャプチャ文字列 | ||||
1 | グループ化 | |||
1-1 | (expression) | グループ化する箇所(丸括弧内をキャプチャする)。 | ||
"大森(一郎|二郎) " | 大森一郎または 大森二郎 にマッチ | |||
大森一郎、大森二郎以外に一郎、二郎が追加でキャプチャされる。 | ||||
1-2 | (?:expression) | グループ化する箇所(丸括弧内をキャプチャしない)。 | ||
"大森(?:一郎|二郎) " | 大森一郎または 大森二郎 にマッチ | |||
大森一郎、大森二郎がキャプチャされ、一郎、二郎はキャプチャされない | ||||
1-3 | (?<name>expression) ※ < >は’でも良い。 | グループ化する箇所(名前を付けて丸括弧内をキャプチャする)。 | ||
"大森(?<name>一郎|二郎) " | 大森一郎または 大森二郎 にマッチ | |||
大森一郎、大森二郎以外に一郎、二郎が追加でキャプチャされる。 ※ このキャプチャ文字列は、グループ名(name)を使用して参照できる。 | ||||
1-4 | (?imnsx-imnsx: expression) | 指定したAPIオプションを部分式に適用(imnsxの部分)または無効(-imnsxの部分)にする。 正規表現のAPIオプション https://msdn.microsoft.com/ja-jp/library/yd1hzczs.aspx | ||
1-5 | (?<name1-name2>expression) | グループ定義を均等化する。 | ||
1-6 | (?>expression) | 非バックトラッキング部分式。 | ||
2 | 先読み・後読み(戻り読み) | |||
2-1 | (?=expression) | 直後にこのパターンが現れることを確認する。 | ||
"\d+(?=%)" | 後ろに「%」が続く数字の連続にマッチ | |||
「%」の部分はキャプチャされない。例えば100%で100がキャプチャされる。 | ||||
2-2 | (?<=expression) | 直前にこのパターンが現れることを確認する。 | ||
"(?<=\\)\d+" | 「\」に続く数字の連続にマッチ。 | |||
「\」の部分はキャプチャされない。例えば\100で100がキャプチャされる。 | ||||
2-3 | (?!expression) | 直後にこのパターンが現れないことを確認する。 | ||
"\d+(?![\d%])" | 後ろに「%」が続かない数字の連続にマッチ。 | |||
「%」の部分はキャプチャされない。例えば100KSで100がキャプチャされる。 | ||||
2-4 | (?<!expression) | 直前にこのパターンが現れないことを確認する。 | ||
"(?<![\d\\])\d+" | 「\」に続かない数字の連続にマッチ。 | |||
「\」の部分はキャプチャされない。例えば$100で100がキャプチャされる。 |
<----------0----------> ( a b ) ( c d ) ( e f ) <--1--> <--2--> <--3-->
入力 : xxxabcdefxxx ・グループ0 : abcdef ・グループ1 : ad ・グループ2 : cd ・グループ3 : ef
<----------------0----------------> ( a ( b ( c ) ( d ) ( e ( f ) ) ) ) <-6-> <-3-> <-4-> <----5----> <-------------2-------------> <----------------1---------------->
入力 : xxxabcdefxxx ・グループ0 : abcdef ・グループ1 : abcdef ・グループ2 : bcdef ・グループ3 : c ・グループ4 : d ・グループ5 : ef ・グループ5 : f
項番 | 区分 | 代替構成体 | 説明 | |
正規表現の例 | マッチする部分文字列 | |||
キャプチャ文字列 | ||||
1 | (?(expression1)expression2) | expression1に一致した場合、そこからexpression2で検索 | ||
"(?(^大森).*郎(\\r?\\n|$))" | 大森一郎、大森二郎、大森三郎、などの行 | |||
先頭が「大森」の場合、末尾が「xxx郎」の行があれば、その行がキャプチャされる。 | ||||
2 | (?(expression)yes_exp|no_exp) | expressionに一致した場合、そこからyes_expで検索 一致しなかった場合、そこからno_expで検索 | ||
"(?(^大森).*郎(\\r?\\n|$)|^品川.*郎(\\r?\\n|$))" | 大森一郎、大森二郎、大森三郎、品川一郎、品川二郎、品川三郎、などの行 | |||
先頭が「大森」の場合、末尾が「xxx郎」の行があれば、その行がキャプチャされる。 また、先頭が「大森」でない場合、先頭「品川」 ~末尾「xxx郎」の行がキャプチャされる。 | ||||
3 | (?(name)yes_exp|no_exp) | 割愛 |
その他の構成体は、正規表現を変更する部分式(APIオプション、コメントなど)を表す。
項番 | その他の構成体 | 説明 |
1 | (? imnsx - imnsx ) | パターンの途中でAPIオプションを適用(imnsxの部分)または無効(-imnsxの部分)にする。 |
2 | (?# ) | 正規表現に挿入するインライン コメント。コメントは、最初の右かっこ文字で終了する。 |
3 | # [行末まで] | X モード コメント。コメントは行末まで継続する。 このコメントを認識させるには、以下の何れかのAPIオプションを有効にする。 ・xオプション ・IgnorePatternWhitespace?オプション |
で参照(利用)できる。
ついて説明する。
前後方参照は、2つ連続する文字(文字グループ)のパターンを検索する場合などに使用する。
グループ番号を使用 | グループ名を使用 | |
正規表現 前後方参照 | "(\\S)\\1" | "(?<ch>\\S)\\k<ch>" |
グループ番号を使用 | グループ名を使用 | |
正規表現 前後方参照 | "\\b(\\S+)\\s+\\1\\b" | "\\b(?<str>\\S+)\\s+\\k<str>\\b" |
項番 | 置換構成体 | 説明 |
1 | $number | グループ番号と一致した部分文字列 |
2 | ${name} | グループ名(name)と一致した最後の部分文字列 |
3 | $& | 一致したパターン全体の文字列 |
4 | $+ | キャプチャされた最後の文字列 |
5 | $_ | 入力文字列全体 |
6 | $` | 一致した場所より前にある入力文字列 |
7 | $' | 一致した場所より後にある入力文字列 |
8 | $$ | 単一の "$" リテラル(エスケープ) |
$0版 | $&版 | |
正規表現 | "s?https?://[-_.!~*'()a-zA-Z0-9;/?:@&=+$,%#]+" | |
置換パターン | "<a href=\"$0\">$0</a>" | "<a href=\"$&\">$&</a>" |
文字列 | |
正規表現 | "^" |
置換パターン | "> " |
文字列 | |
正規表現 | "[\\t]+(?=\\r?\\n|$)" |
置換パターン | "" (空文字列) |
文字列 | |
正規表現 | "[^\\w\\.@-]" |
置換パターン | "" (空文字列) |
グループ番号を使用 | グループ名を使用 | |
正規表現 | "^(.*)(\\r?\\n\\1)+$" | "^(?<line>.*)(\\r?\\n\\k<line>)+$" |
置換パターン | "$1" | "${line}" |
グループ名を使用 | |
正規表現 | "(?<year>\\d{2,4})/(?<month>\\d{1,2})/(?<day>\\d{1,2})" |
置換パターン | "${year}年${month}月${day}日" |
グループ名を使用 | |
正規表現 | "(?<month>\\d{1,2})/(?<day>\\d{1,2})/(?<year>\\d{2,4})" |
置換パターン | "${day}-${month}-${year}" |
デフォルトでは「最長マッチ」となるため、必要に応じて「最短マッチ」を使用する。
"「.*」"
"・・・「あ」、「い」、「う」・・・"
"「あ」、「い」、「う」"
"「あ」"、"「い」"、"「う」"
"「.*」" → "「.*?」"
正規表現を使用したパターン マッチの例を示す。
※ IgnoreCase?(大文字と小文字を区別しない)オプションを設定する必要がある。
※ 文章中から検索する場合は、前後に「\b」を付与する必要がある。
また、日本語文章中の場合は、実行時、ECMAScriptオプションを設定する必要がある。
※ ハイライトの「\」は、リテラル中の「\」のエスケープ。
正規表現 | "[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}" |
"([\\w-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([\\w-]+\\.)+))([A-Z]{2,4}|[0-9]{1,3})(\\]?)" |
※ 上記は、前方参照、最小マッチを併用している。
※ ハイライトの「\」は、リテラル中の「\」のエスケープと、
C#に於ける「"」のエスケープ(VBの場合は「"」を使用)。
正規表現 | "href\\s*=\\s*(?:(?<quot>[\"'])(?<url>.*?)\\k<quot>)" →「クォーテーション無し」を考慮していない例。 |
"href\\s*=\\s*(?:\"(?<1>[^\"]*)\"|(?<1>\\S+))" →「シングル クォーテーション」を考慮していない例。 |
※ 上記は、前方参照、最小マッチを併用している。
※ 実行時、Singleline(「.」に、\nを含める)オプションを設定する必要がある。
※ ハイライトの「\」は、リテラル中の「\」のエスケープ。
正規表現 | "<(h[1-6])\\b[^>]*>(.*?)</\\1>" |
※ 上記は、前方参照、最小マッチを併用している。また、url、textなどの部分キャプチャを行なっている。
※ 実行時、IgnoreCase?(大 / 小文字を区別しない)、Singleline(「.」に、\nを含める)オプションを設定する必要がある。
※ ハイライトの「\」は、リテラル中の「\」のエスケープと、
C#に於ける「"」のエスケープ(VBの場合は「"」を使用)。
正規表現 | "<a\\s+[^>]*href\\s*=\\s*(?:(?<quot>[\"'])(?<url>.*?)\\k<quot>|(?<url>[^\\s>]+))[^>]*>(?<text>.*?)</a>" |
※ 最小マッチを使用している。また、プロトコル、ポート番号などの部分キャプチャを行なっている。
※ ハイライトの「\」は、リテラル中の「\」のエスケープ。
正規表現 | "^(?<proto>\\w+)://[^/]+?(?<port>:\\d+)?/" |
正規表現の処理に利用するAPIと、そのオプションについて説明する。
正規表現にて中心的役割を担うクラスにRegexクラスとMatchクラスがある。
Regexクラスは、正規表現パターンを格納し、パターン マッチングを実行するメソッドを備えたクラスである。
このオブジェクトからキャプチャ文字列の値を取り出して、引き続き、「手続き型の処理」を実装できる。
項番 | 区分 | 名前 | 説明 |
1 | プロパティ | ||
1-1 | Options | Regexコンストラクタに渡されたオプション(5.2節を参照) | |
2 | メソッド | ||
2-1 | IsMatch? | 正規表現と一致する対象が入力文字列内で見つかったかどうかを示す。 主に、入力チェックを実装する場合に利用し、入力チェックでは、 正規表現の先頭と末尾に「 ^ 」と「 $ 」を付与して中間からのマッチを拒否すると良い。 | |
2-2 | Match | 入力文字内で正規表現と一致する対象を1つ検索し、結果をMatchオブジェクトとして返す。 取得したMatchオブジェクトのNextMatch?メソッド(後述)が呼び出された場合、次の結果をMatchオブジェクトとして返す。 | |
2-3 | Matches | 入力文字列内で正規表現と一致する対象をすべて検索し、 結果の複数のMatchオブジェクト(見つかった対象をすべて返す)をMatchCollection?として返す。 | |
2-4 | Replace | 第一引数の正規表現パターンに一致する文字列を、第二引数の置換パターンで置換する。 第二引数にはMatchEvaluator?デリゲートを使用して置換(変換)することもできる(後述)。 | |
2-5 | Split | 入力文字列を、正規表現によって定義されている位置で配列に分割する。 |
オブジェクト名 : 下位オブジェクトの取得方法 : キャプチャ文字列の詳細データ MatchCollectionオブジェクト : インデクサ(番号) ┗ Matchオブジェクト : Groupsプロパティ ┗ GroupsCollectionオブジェクト : インデクサ(番号、名称) ┗ Groupsオブジェクト : Capturesプロパティ ┗ CaptureCollectionオブジェクト : インデクサ(番号) ┗ Captureオブジェクト : 各種プロパティ ┣ Value(string) : キャプチャ文字列の値 ┣ Length(int) : キャプチャ文字列の長文字列 ┗ Index(int) : 入力文字列を基にした位置(インデックス)
項番 | オブジェクト名 | 説明 |
1 | Matchオブジェクト | 正規表現により「検索された1つの文字列」と対応する結果を格納。 |
2 | Groupsオブジェクト | 上記「検索文字列」のキャプチャ、クループ化による追加キャプチャの情報を格納。 |
3 | Captureオブジェクト | キャプチャ文字列の詳細データを格納 |
正規表現 | "(123)(\\d)+(789)" |
入力文字列 | "123456789-123456789" |
public class Test_Regex { // 正規表現を使用して置換(変換)するメソッド public string Regex_Replace(string yyyymmdd) { // 日付(yyyy/mm/dd形式)を正規表現を用いて1日増やす return Regex.Replace(yyyymmdd, @"(?<year>\d{4})/(?<month>\d{2})/(?<day>\d{2})", new MatchEvaluator(this.IncrementDay)); } // MatchEvaluatorデリゲートメソッド private string IncrementDay(Match m) { // 日付ワーク DateTime dt; // 日付(yyyy/mm/dd形式)をDateTime型に変換 if (DateTime.TryParse(m.Value, out dt)) { // DateTimeクラスを使用して1日増やし、 // 日付(yyyy/mm/dd形式)に戻す。 return dt.AddDays(1).ToShortDateString(); } else { // 変換できなかった場合、何もしないで戻す。 return m.Value; } } }
Matchクラスは、Regexクラスで実行されたパターン マッチングの結果を格納するクラスである。
項番 | 区分 | 名前 | 説明 |
1 | プロパティ | ||
1-1 | Success | 一致した対象が見つかったかどうかを示すbool値を取得する。 例えば、量指定子「 * 」を指定したグループ構成体は、見つからないことが有り得る。 | |
1-2 | Groups | 正規表現による「検索文字列」の ・キャプチャ(グループ0)、 ・グループ化による追加キャプチャ(グループ1 ~ ) の情報を格納。 | |
1-3 | Captures | グループ0のキャプチャ | |
1-4 | Value | グループ0のキャプチャ文字列の値 | |
1-5 | Length | グループ0のキャプチャ文字列の文字列長 | |
1-6 | Index | グループ0の入力文字列を基にした位置(インデックス) | |
2 | メソッド | ||
2-1 | NextMatch? | 次の結果をMatchオブジェクトとして返す。 | |
2-2 | Result | 指定された置換パターンを返す(結果毎に置換パターンを変更できる)。 |
以下、Regexクラスのオプションについて説明する。
これによって一部、動作(処理結果)が変更される。
項番 | RegexOptions?列挙体のメンバ | 説明 |
1 | None | オプションが何も設定されないことを指定する。 |
2 | ECMAScript | ECMAScript準拠の動作とする。一部のメタ文字の意味が変更される。 ・ECMAScript とします。 標準一致の動作 http://msdn.microsoft.com/ja-jp/library/04ses44d.aspx |
3 | Singleline | ワイルドカードである.(ピリオド)の意味を、「\n」を含めたすべての文字の意味に変更する。 |
4 | Multiline | 「^」と「$」の意味を ・「^」:「文字列の先頭」 → 「行の先頭」 ・「$」:「文字列の末尾」 → 「行の末尾」 に変更する。 「^」と「$」の代わりに「\A」と「\Z」を使用すると、 Multilineの影響を受けずに「文字列の先頭」、「文字列の末尾」を指定できる 。 |
5 | IgnoreCase? | 大文字と小文字を区別しない。 |
6 | CultureInvariant? | 言語(カルチャ)の違いを無視する。 ・RegularExpressions? 名前空間でのカルチャを認識しない操作の実行 http://msdn.microsoft.com/ja-jp/library/z0sbec17.aspx |
7 | RightToLeft? | 検索が左から右(→)ではなく右から左(←)に行われるように指定する。 |
8 | Compiled | 正規表現をコンパイルして実行速度を上げる。ただし、起動時間は長くなる。 ・正規表現におけるコンパイルと再利用 http://msdn.microsoft.com/ja-jp/library/8zbs0h2f.aspx |
9 | ExplicitCapture? | 明示的に名前を指定されたグループだけが有効なキャプチャであることを指定する。 |
10 | IgnorePatternWhitespace? | ・正規表現のパターン内にコメント文を記述するには?[C#、VB] - @IT http://www.atmarkit.co.jp/fdotnet/dotnettips/582regexcomment/regexcomment.html |
正規表現を使用すると、高度な、
などの処理を、高い生産性で実装することができる。
ただし、以下の点は、正規表現により解決できない。
共通処理を、比較的容易に開発できる。