C# 正規表現でテキスト解析

以前も似たようなものを作った。

正規表現基本

^
行頭(改行コードの後でもマッチする)

$
行末(改行コードの前でもマッチする)

\A
文字列の先頭にマッチ(改行コードの後ではマッチしない)

\Z
文字列の末尾にマッチ(改行コードの前ではマッチしない)
(文字列の最後が改行の場合のみ改行コードの前でマッチする)

\z
文字列の最後も含め改行コードの前ではマッチしない

.
任意の1文字(改行は除くmオプションで改行含む)

|
または

( )
グループ化

文字クラス

[ ]
文字クラス(文字集合)


文字クラス内で範囲

^
文字クラス内で先頭のみ否定(文字集合以外の文字という意味)

数量子

*
0以上(?で最短マッチ)

+
1以上(?で最短マッチ)

?
0 か 1 か

{m,n}
m から n(片方を省略すると以上、以下)

メタ文字

\s
空白(\Sは空白以外)

\n
改行

\t
タブ文字

\w
文字(\Wは文字以外)

\d
数字(\D数字以外)

走査の順番

文字列:abcdefgab
パターン:cf

走査の順番は、走査される文字列(abcdefgab)の先頭(a)から
パターンと照合し、ダメなら次の文字列のbからパターンと照合。
文字列のcまでくると、パターンのcとマッチするので、
パターンは次のfに行く。
そこで、文字列がbでパターンがfなのでマッチが失敗。
走査の対象にパターンと同じ組み合わせがでてこないとダメ。

先読み・後読み

アンカーにマッチする。もとの走査とは別の走査。

・肯定的先読み
foo(?=bar)

走査してbarが見つかると、barの直前にマッチする。
結果、直後にbarがあるfooにマッチする。

・否定的先読み
foo(?!bar)

走査時、全ての位置にマッチし、barがあると直前をマッチから外す
結果、直後にbarがないfooにマッチする。

・肯定的後読み
(?<=bar)foo

走査してbarが見つかると、barの直後にマッチする。
結果、直前にbarがあるfooにマッチする。

・否定的後読み
(?<!bar)foo

走査時、全ての位置にマッチし、barがあると直後をマッチから外す
結果、直前にbarがないfoo(barは含まない)にマッチする。

***

(?)は固定で、?の後に=か!がくる。アンカーをパターンの後ろにしたい場合、
=か!の前に<をつける。

パターンを含む行
^.*abc.*

パターンを含まない行
^(?!.*abc).*

実験(電話番号)

(?=(?:\d-?){10}$|\d{3}-\d{4})(\d{2,5})-(\d{1,4})-(\d{4}$)
の場合
(?=(?:\d-?){10}$|\d{3}-\d{4})
まで先読み。

まずこのマッチは?:を(?:はメモリしない意)外して考える。
(\d-?){10}
これはハイフンは無視して数字が10連続しているかどうか。
NG 123456789
NG 123456789a
NG 123456789a0
OK 1234567-8-9-0
OK 1234567890
OK 123456789-0

\d{3}-\d{4}
を追加して、
(\d-?){10}|\d{3}-\d{4}
とすると。
OK 123-4567
NG 1234-567
NG 12-34567

この先読みでマッチした場合のみ、後ろの、
(\d{2,5})-(\d{1,4})-(\d{4}$)
へ走査が続く。

・参考

文字列を含まない行
^(?!.*name).*

文字列より前
^.*?(?=name)

・カンマ区切り