正規表現 正規表現の概要 此処では.NET Framework の正規表現に付いて 主に正規表現パターンに付いて 基本を極く簡単に説明する 猶.NET Framework の正規表現は Perl5 の正規表現に対応する様にデザインされて居るので Perl の正規表現を理解して居れば問題は無い ( 勿論 理解して居なくても問題は無い ) 正規表現で出来る事 正規表現は 文字列を検索する為に使用する 正規表現を使うと 可成り複雑な検索が可能で有る 正規表現を利用する主なケースには 下記の様な物が挙げられる 文字列内に指定されたパターンと一致する部分が有るか調べる 例えば 入力された文字列が電子メールアドレスと仕て適当か調べる等 文字列から指定されたパターンと一致する部分を検索 抽出する 例えば 文字列内に有る URL の部分を総て抜き出す等 文字列から指定されたパターンと一致する部分を探して別の文字列に置換する 例えば 文字列内に有る URL にリンク (<a> タグ ) を付けたり HTML のタグを削除する等 補足 : 此等以外にも 文字列を分割して配列にする場合にも使用出来る 此の場合は Regex.Split メソッドを使用する パターンの記述法 或る文字列と一致する部分を検索すると謂う事を指定するには 其れを表現したパターンを書く必要が有る 適切なパターンを書ける様に成る事が 正規表現を勉強する最大の目標と成るで有ろう パターンは ファイルの検索等で使用される * や? 等のワイルドカードを理解して居るならば 此れと同じ様な物だと思って結構で有る 例えば 文字列から或る郵便番号と一致する部分を探し度いとする 其の郵便番号が決まって居り 123-4567 で有るならば パターンは 123-4567 の儘で良い 但し 此の様に探し度い文字列が決まって居るならば 正規表現を使う意味は無い 決まった郵便番号ではなく 郵便番号形式の文字列を探し度い 詰まり 何等かの数字が 3 個続き ハイフン ( - ) が挟まり 亦 数字が 4 個続く文字列 を探し度いと謂う事で有れば 正規表現が役に立つ 此の様な場合 書く可きパターンは d d d- d d d d と成る ( 別の書き方も出来る ) 詰まり d は 何等かの数字 1 文字 を意味する 此の様に正規表現のパターンでは 等の特定の文字列が特別な意味を持って居る 此の様な特別な意味を持つ文字を メタ文字 ( メタキャラクタ ) と呼ぶ -1-
正規表現の基本 簡単な例.NET で正規表現を扱うには Regex クラスを使用する 以下に Regex クラスを使って文字列の検査 抽出 置換を行う簡単な例を示す 更に詳しい例に付いては 正規表現詳細を参照され度い Visual Basic ' txtsrc に郵便番号形式の文字列が含まれて居るか調べる If System.Text.RegularExpressions.Regex.IsMatch( _ txtsrc.text, " d d d- d d d d") Then MessageBox.Show(" 郵便番号が含まれて居る ") End If ' txtsrc 内の郵便番号形式の文字列を総て抽出する Dim mc As System.Text.RegularExpressions.MatchCollection = _ System.Text.RegularExpressions.Regex.Matches( txtsrc.text, " d d d- d d d d") For Each M As System.Text.RegularExpressions.Match In mc MessageBox.Show(M.Value) Next ' txtsrc 内の郵便番号形式の文字列の "-" を削除して で囲む txtsrc.text = System.Text.RegularExpressions.Regex.Replace( _ txtsrc.text, "( d d d)-( d d d d)", " $1$2 ") C# // txtsrc に郵便番号形式の文字列が含まれて居るか調べる if (System.Text.RegularExpressions.Regex.IsMatch(txtSrc.Text, @" d d d- d d d d")) { MessageBox.Show(" 郵便番号が含まれて居る "); } // txtsrc 内の郵便番号形式の文字列を総て抽出する System.Text.RegularExpressions.MatchCollection mc = System.Text.RegularExpressions.Regex.Matches(txtSrc.Text, @" d d d- d d d d"); foreach (System.Text.RegularExpressions.Match m in mc) { MessageBox.Show(m.Value); } // txtsrc 内の郵便番号形式の文字列の "-" を削除して で囲む txtsrc.text = System.Text.RegularExpressions.Regex.Replace( txtsrc.text, @"( d d d)-( d d d d)", " $1$2 "); -2-
メタ文字一覧 下記に 良く使われるメタ文字と其の意味を紹介する 詳しくは MSDN の 正規表現言語要素 を参照され度い 或る 1 文字を表す文字 ( アトム ) 文字説明使用例.( ドット ) s d w 改行文字 ( n) 以外の任意の一文字 ( 但し [ ] 内ではピリオド文字 ) 空白文字 改行文字 タブ文字 半角 / 全角スペース文字等 [ f n r t v x85 p{z}] と同じ ( 因みに S は s 以外の文字を表す ) 0 から 9 までの数字 全角を含む p{nd} と同じ ( 因みに D は d 以外の文字を表す ) 単語に使用される文字 アルファベット 数字 アンダーバー (_) ひらがな カタカナ 漢字等 [ p{ll} p{lu} p{lt} p{lo} p{nd} p{pc} p{lm}] と同じ ( 因みに W は w 以外の文字を表す ) r キャリッジリターン ( u000d と同じ ) n ラインフィールド ( 改行文字 u000a と同じ ) t タブ ( u0009 と同じ ) 文字の前に を付けると 其の文字 メタ文字の機能を無効にする時に使う ( 或る文字列内のメタ文字を総て でエスケープするには Regex.Escape メソッドを使うと良い ) [ ] [ ] 内のどれか 1 文字 ([abc] ならば a か b か c) [^ ] [ - ] [^] 内の文字以外の 1 文字 ([^abc] ならば a か b か c 以外の文字 ) 連続した文字範囲の 1 文字 ([0-9] ならば数字 1 文字 [a-za-z] ならばアルファベット 1 文字 ) u0000 4 桁の 16 進数で表される Unicode 文字 x00 2 桁の 16 進数で表される ASCII 文字 -3-. 内に任意の 1 文字が有る箇所にマッチ Visual sbasic Visual と Basic の間に空白文字が 1 文字有る箇所にマッチ VB d VB の後に数字が 1 文字有る箇所にマッチ w 内に単語に使用される文字が 1 文字が有る箇所にマッチ r n Windows の改行文字 (CRLF) にマッチ r n Windows の改行文字 (CRLF) にマッチ n t 改行文字 ( n) の後にタブが続く箇所にマッチ DOBON.NET DOBON.NET にマッチ VB[2456] VB の後に 2 か 4 か 5 か 6 が続く箇所にマッチ [^ ] 内に 以外の 1 文字が有る箇所にマッチ VB[24-6] VB の後に 2 か 4 か 5 か 6 が続く箇所にマッチ [ uff61- uff9f] 半角カナ文字の 1 文字にマッチ [ x20- x7f] 半角英数記号文字 ( 0x20 ~ 0x7F) の 1 文字にマッチ
文字列内の位置を表す文字 ( アトミックゼロ幅アサーション アンカー 位置指定子 ) 此処で紹介するメタ文字は 文字列内の位置を表現した物で有る 文字とマッチする訳では無い ^ $ b 文字説明使用例 ^ d 文字列の先頭先頭に有る数字 1 文字にマッチ 文字列の末尾 ( 但し 文字列の末尾が n の時は 其の前と一致 末尾が n でも末尾で一致させるには z を使う ) 単語の境界 ( w と W の間 ) と一致 ( 但し [ ] 内ではバックスペース文字 因みに B は b 以外の境界を表す ) d$ 末尾に有る数字 1 文字にマッチ bvb b VB が単語と仕て現れる箇所にマッチ 文字の繰り返しを表す文字 ( 量指定子 ) 此処で紹介する量指定子は 文字 ( 又は グループ ) の繰り返しを表現する物で有る 最長マッチと最短マッチの違いは非常に重要だが 此れに付いては後述する 文字説明使用例 <[^>]*> * 直前の文字が 0 回以上繰り返す <> で囲まれた箇所にマッチ + 直前の文字が 1 回以上繰り返す? 直前の文字が 0 回 又は 1 回繰り返す {n,m} {n} {n,} *? 直前の文字が n 回以上 m 回以下繰り返す 直前の文字が n 回繰り返す 直前の文字が n 回以上繰り返す 最短マッチで 0 回以上の繰り返し (? は * +? { } の後に付けて最短マッチを表す事が出来る 最短マッチと最長マッチに付いては 後述 ) <[^>]+> <> 内に 1 文字以上有る箇所にマッチ -? d+ マイナスが付いた数字 或るいは付かない数字にマッチ d{2,6} 数字が 2 文字以上 6 文字以下続いて居る箇所にマッチ d{6} 数字が 6 文字続いて居る箇所にマッチ d{8,} 数字が 8 文字以上続いて居る箇所にマッチ <.*?> <> で囲まれた箇所にマッチ 選択 グループ化等を表す文字 此処で紹介するグループ化を使用する主なケースと仕ては 論理和に依る選択を行う場合や 前方参照 ( 後述 ) や Match.Groups プロパティでの抽出を行い度い場合等が挙げられる -4-
.NET Framework にはグループに名前 ( 或るいは番号 ) を付ける事が出来ると謂う特徴が有る グループに名前を付けても付けなくても グループには 1 から連番で番号が付けられる ( 番号 0 はパターン全体で有る ) 此処では先読み 後読みアサーションも紹介して居るが 此等は少し高度で有る 従って 初心者は 此等を無視しても良いが 知って置くと可成り役に立つ 因みに 後読みアサーションのパターンとマッチする文字列は固定長でなければ成らないとするエンジンが多いが.NET Framework では此の様な制限が無い 文字 説明 使用例 リンゴ りんご 林檎 で区切られた文字列の孰れか ( 論理和 ) リンゴ又はりんご又は林檎にマッチ ( ) グループ化する箇所 山田 ( 太郎 花子 ) 山田太郎又は山田花子にマッチ (?<name> ) グループに名前 ( 或るいは番号 ) を付ける ( 因みに < > の代わりに ' で括る事も出来る ) (?: ) キャプチャしないグループ (?= ) (?! ) (?<= ) (?<! ) 直後に此のパターンが現れる事を確認する ( ゼロ幅の肯定的先読みアサーション ) 直後に此のパターンが現れない事を確認する ( ゼロ幅の否定的先読みアサーション ) 直前に此のパターンが現れる事を確認する ( ゼロ幅の肯定的後読みアサーション ) 直前に此のパターンが現れない事を確認する ( ゼロ幅の否定的後読みアサーション ) VB(?<ver> d) VB の後に数字が有る箇所にマッチし 数字を "ver" と謂うグループ名でキャプチャ山田 (?: 太郎 花子 ) 山田太郎又は山田花子にマッチするが 太郎又は花子をキャプチャしない d+(?=%) 後ろに % が続く数字の連続にマッチ 但し % はマッチした箇所に含まれないし グループと仕てキャプチャもされない d+(?!%) 後ろに % が来ない数字の連続にマッチ (?<= ) d+ に続く数字の連続にマッチ 但し はマッチした箇所に含まれないし グループと仕てキャプチャもされない (?<! ) d+ 前に がない数字の連続にマッチ 前方参照 ( 後方参照 ) を表す文字 グループ化してキャプチャした文字列を後から参照する事が出来る 此れが前方参照 ( 後方参照 ) で有る 此れに依り キャプチャした文字列をパターンに埋め込む様な事が出来る -5-
文字 説明 使用例 number 番号が number のグループと一致した文字列 <(H d)>.*?</ 1> <H> タグで囲まれた箇所にマッチ k<name> 名前が name のグループと一致した文字列 ( 因みに < > の代わりに ' で括る事も出来る ) <(?<tag>h d)>.*?</ k<tag>> <H> タグで囲まれた箇所にマッチ 置換パターンで使用出来る特殊文字 前方参照 ( 後方参照 ) と同じ様に置換パターン内で以下の様な特殊文字を使用する事が出来る 前方参照と似て居る為 使用例は省略する 使用例は 正規表現応用を参照され度い 文字 $number ${name} $& 説明番号が number のグループと一致した文字列名前が name のグループと一致した文字列パターン全体と一致した文字列 良く使われるオプション オプションを指定する事も出来る オプションを指定するとメタ文字の意味が多少変わる物も有る.NET ではオプションを指定するのに RegexOptions 列挙体を使用する ( インラインで使用する方法も有るが 此処では紹介しない ) 以下に良く使われる重要なオプションを示す RegexOptions 列挙体のメンバ IgnoreCase Singleline Multiline ECMAScript 説明 大文字と小文字を区別しない.( ピリオド ) の意味を変更し n を含めた総ての文字と一致する様にする ^ と $ の意味を変更し 文字列全体の先頭と末尾丈でなく 行の先頭と末尾にも一致する様にする 具体的には ^ は n の後 $ は n の前 ( 改行文字が r n で有ったと仕ても ) にも一致する様に成る ^ と $ の代わりに A と Z を使用すると Multiline の影響を受けずに文字列全体の先頭と末尾に一致させる事が出来る ECMAScript 準拠の動作とする 此の事で 一部のメタ文字の意味が変更される 例えば w は [a-za-z_0-9] と同じに s は [^ f n r t v] と同じに d は [0-9] と同じに成る CultureInvariant 言語の違いを無視する Compiled 正規表現をコンパイルして実行速度を上げる ( 但し 起動時間は長く成る ) 最長マッチと最短マッチ 最長マッチと最短マッチの違いは非常に重要なので 此処で説明して置く 例えば 鈎括弧 ( ) で囲まれた文字列を抽出する為に次の様なパターン ( コード ) を書いたとする -6-
Visual Basic Dim Mc As System.Text.RegularExpressions.MatchCollection = _ System.Text.RegularExpressions.Regex.Matches( txtsrc.text, ".* ") C# System.Text.RegularExpressions.MatchCollection mc = System.Text.RegularExpressions.Regex.Matches(txtSrc.Text, @".* "); 此の様なパターンでは 鈎括弧が複数有った場合 問題が起こる 例えば txtsrc に " あ い う " と入力されて居るならば マッチする文字列は " あ い う " の 1 つ丈で有る " あ " " い " " う " の 3 か所にマッチする様にするには パターンを ".*? " と書き換える 詰まり "*" の後ろに "?" を付けて 最短マッチにする "?" を付けないと最長マッチに成るので 一致する箇所が最も長く成る様な方法で検索が行われる 因みに上記の様な例で有れば 最短マッチにしなくても " [^ ]* " と書けば 粗同じ事が出来る 参考.NET Framework の正規表現 -7-