第5章 正規表現
T2Xではテキストより部分文字列を抽出するために正規表現という手法を用いています。このページではT2Xの利用に必要な正規表現について説明します。
5.1 正規表現とは
正規表現とは、テキスト中の特定の文字列をパターン化して表現する手法をいいます。例えばテキスト中の郵便番号を探す場合に、郵便番号が〒918-1234のような形式で書かれていれば、正規表現では郵便番号を 〒\d{3}\-\d{4} というパターンで表します。
この正規表現の方法は、プログラム言語ごとに多少の差異があります。T2XではMicrosoft .NET Frameworkの正規表現を利用しています。Microsoft .NET Frameworkの正規表現はPerl5に準拠し非常に強力なパターンマッチ機能を備えています。
5.2 メタ文字
正規表現のパターンを表すにはリテラルとメタ文字を使用します。リテラルは文字がそのまま記述した通りの文字を表します。たとえばAはそのままAという文字を現します。一方、メタ文字は記述した文字は、文字がそのまま記述した文字を表すのではなく別の意味を持ちます。例えば $ は $ を現すのではなく行末を現します。
メタ文字は次の14文字です。
\ ^ . $ * + ? | ( ) [ ] { }
このメタ文字をリテラルとして使用したい場合には、メタ文字の前に \ を付加します。 \ を文字として使用するには \\ と記述します。このような \ をエスケープと呼びます。また反対に、リテラルにエスケープを付加することにより、リテラルとしてではなく別の意味を持たせることができます。
メタ文字の意味は一意ではなく、使用する場所により意味が異なるものもあります。またメタ文字として使う場所が決められていて、それ以外の場所ではエスケープなしでリテラルとして利用できるものもあります。例えば - は [ ] の中ではメタ文字ですが、それ以外ではリテラルとなります。従って [ ] の中で - をリテラルとし使用する場合のみエスケープが必要です。しかしこれ以外の場合でもエスケープを付加しても間違いではありませんので、紛らわしい場合はエスケープを付加してもかまいません。
5.3 パターンの記法
正規表現のパターンは次の要素およびリテラルを組合せて表現します。
1. 任意の1文字
ピリオド( . )は任意の1文字を表します。但し改行は含まれません。
. | 改行を除く任意の1文字 |
Singlelineオプションを指定すると改行を含む全ての1文字を表すようになります。
2. 文頭・文末
文頭、文末は各々 ^ と $ で表されます。
^ | テキストの先頭にマッチ |
$ | テキストの末尾にマッチ |
Multilineオプションを指定するとテキスト全体の文頭、文末ではなく、各行の行頭、行末を意味するようになります。
3. 文字クラス
指定した文字集合の中の任意の1文字を表すには文字クラスを使用します。
[ ] | 文字集合の中の任意の1文字 |
文字クラスは集合に含まれる文字を [ ] 内に列記します。例えば「[ABC]」はAまたはBまたはCのいずれかの1文字を表します。
[ ] 内には文字を列記する他に、下記のように - を用いて範囲指定することもできます。
文字クラス | 意味 |
---|---|
[a-z] | 英小文字のいずれか1文字 |
[A-Z] | 英大文字のいずれか1文字 |
[0-9] | 数字1文字 |
[a-zA-Z0-9] | 英数字1文字 |
[ ] 内の先頭に ^ を付けると否定になり、指定した文字集合以外の1文字を表します。
[^a-zA-Z] | 英字以外にマッチ |
[^0-9] | 数字以外にマッチ |
文字クラス内に - または [ を文字として指定したい場合は \ を付ける必要があります。一方その他のメタ文字を文字として指定したい場合は \ をつける必要はありません。
4. 省略形
よく使用する文字クラスには次のような省略形が用意されています。
\w | 英字、数字、アンダースコア。[a-zA-Z0-9_] に同じ。 |
\W | 英字、数字、アンダースコア以外の文字。[^a-zA-Z0-9_] に同じ。 |
\d | 数字。[0-9] に同じ。 |
\D | 数字以外の文字。[^0-9] に同じ。 |
\s | スペース。[ \r\t\n\f] に同じ。 |
\S | スペース以外の文字。[^ \r\t\n\f] に同じ。 |
5. 特殊文字
文字として表記できない特殊な文字はエスケープ記号を用いて次のように表現します。
\t | タブ |
\r | リターン(復帰文字) |
\n | 改行 |
\f | ラインフィード(改ページ) |
\a | アラーム(ベル) |
\d | バックスペース |
\e | エスケープ |
\0 + 数字 | 8進法で表すASCII文字。( ex. \033, \040 など ) |
\x + 英数字 | 16進法で表すASCII文字。( ex. \x1b, \x00 など ) |
6. 量指定子
量指定子とは文字の繰返し回数を指定するためのものです。
* | 直前の文字を0回以上にマッチ |
+ | 直前の文字を1回以上にマッチ |
? | 直前の文字を0又は1回にマッチ |
{n} | 直前の文字をn回にマッチ |
{n,} | 直前の文字をn回以上にマッチ |
{n,m} | 直前の文字をn回以上、m回以下にマッチ |
パターン「ABC{3}」はテキスト「ABCCC」とマッチします。
パターン「[0-9]+」は1桁以上の数字とマッチします。
7. 最短マッチの量指定子
上記の量指定子を用いた場合は、条件を満たす最長の文字列とマッチするように動作します。条件を満たす最短の文字列と一致するようにするには 量指定子に ? を付加します。
*? | 直前の文字を0回以上に最短マッチ |
+? | 直前の文字を1回以上に最短マッチ |
?? | 直前の文字を0又は1回に最短マッチ |
{n}? | 直前の文字をn回に最短マッチ |
{n,}? | 直前の文字をn回以上に最短マッチ |
{n,m}? | 直前の文字をn回以上、m回以下に最短マッチ |
8. グループ化
纏まりのあるパターンを ( ) で括りグループ化することができます。グループ化されたパターンは量指定子でグループ単位で繰返し回数を指定できます。また後述のようにグループ化されたパターンに一致する部分文字列を取り出すことも可能です。
( ) | グループ化 |
(例) 〒(\d{3}-\d{4})
9. 選択
複数の条件の一つが満たされればよい場合は、複数のパターンを | で区切って記述することにより、複数パターンを選択することができます。
(例) 東京|大阪|名古屋
| | 選択 |
選択パターンと他のパターンを連結する場合は選択パターンを ( ) で括りグループ化します。
(例) (東京|大阪|名古屋)在住
5.4 先読み・後読み
先読み
一つのパターンで複数の抽出を行う場合があります。例えば
〒106-0032
港区六本木7-22-2
立新美術館
〒153-0063
東京都目黒区三田1丁目
恵比寿ガーデンプレイス内
東京都写真美術館
〒110-0007
台東区上野公園7番7号
国立西洋美術館
〒135-0022
江東区三好 4-1-1
東京都現代美術館
〒102-0092
千代田区北の丸公園3
東京国立近代美術館
のようなテキストから住所を抽出する場合は〒が住所の句切りとして利用できますので、抽出パターンは「〒(.*\n)*?〒」と書けそうです。しかしながらこのパターンでは一つ置きにしか抽出されません。それは最初の抽出で2つ目の〒まで読込まれてしまうので、2番目の住所はパターンに一致しなくなります。このようなときに利用するのが先読み機能です。先読みはパターン認識には利用されますが、抽出には含まれません。また読込み位置は進めません。先読みの記述方法は次の通りです。
(?=pattern) | 肯定的先読み |
(?!pattern) | 否定的先読み |
肯定的先読みとはpatternが現れる場合、否定的先読みとpatternが現れない場合を意味します。上の例の場合は肯定的先読みを用いて「〒(.*\n)*?(?=〒)」のパターンで正しく抽出できます。
後読み
先読みとよく似た機能に後読みがあります。後読みは抽出内容には含まれませんが、読込み位置は進められます。
(?<pattern) | 肯定的後読み |
(!>pattern) | 否定的後読み |
5.5 名前付きグループ
正規表現ではパターンの中の一部を括弧( )で囲んでグループ化することができます。グループ化するとその部分に対応した部分文字列が得られます。またグループには名前を付けることができます。グループに名前を付けると名前の付いた部分文字列を得ることができます。名前付きグループは次のように記述します。
(?<名前>pattern) | 名前付きグループ |
例えば
東京都庁 〒163-8001 東京都新宿区西新宿2丁目
から郵便番号と住所を抽出する場合、「〒(?<郵便番号>\d{3}-\d{4})\s*(?<住所>.*)」というパターンで抽出を行うと、郵便番号という名前で「163-8001」が、住所という名前で「東京都新宿区西新宿2丁目」を得ることができます。
T2Xでは、この名前付きグループを用いて必要な文字列の抽出を行います。