この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。
本稿では、ある文字列内から特定のパターンにマッチする部分文字列を抜き出す処理について、正規表現を使った場合の基本的な手順をまとめる。
ここでは例として、HTMLから、
<a href="URL" ……>テキスト</a>
のような形式のアンカー要素に対して、URL部分とテキスト部分を取り出す場合を考えてみよう。
このようなアンカー要素にマッチする正規表現は次のようになる。
<a href="(?<url>.*?)".*?>(?<text>.*?)</a>
2個所ある「(」と「)」で囲まれた部分は「グループ化」を行っており、それぞれに対して「?<url>」「?<text>」により、「url」と「text」というグループ名を付けている。
ちなみに「.*?>」の部分で使用している「?」は最短一致を指定するもので、「.*?>」は、「>」以外の任意の文字の並び+「>」、を表すことになる(「.*?)」の部分も同様)。
まず、上記の正規表現を表すRegexクラス(System.Text.RegularExpressions名前空間)のオブジェクトを作成する。
Regex reg = new Regex("<a href=\"(?<url>.*?)\".*?>(?<text>.*?)</a>",
RegexOptions.IgnoreCase | RegexOptions.Singleline);
Dim re As New Regex("<a href=""(?<url>.*?)"".*?>(?<text>.*?)</a>", _
RegexOptions.IgnoreCase Or RegexOptions.Singleline)
ここでは第2パラメータで2つのオプションを指定している。RegexOptions.IgnoreCaseは大文字小文字を区別せずにマッチするためのものだ。これにより「<A HREF=……」のようなアンカー要素にもマッチするようになる。RegexOptions.Singlelineは任意の1文字を示す「.」を改行文字にもマッチさせるためのものだ。これにより1つのアンカー要素が複数行に渡って記述されていてもマッチするようになる。
次にマッチングを実行し、最初にマッチした部分をMatchクラス(System.Text.RegularExpressions名前空間)のオブジェクトとして取得する。これにはRegexオブジェクトのMatchメソッドを呼び出す。Matchメソッドのパラメータには、検索対象となるテキストを文字列で指定する(本稿の例ではHTMLの内容)。
Match m = reg.Match(<検索対象となる文字列>);
Dim m As Match = reg.Match(<検索対象となる文字列>)
ただし、マッチする部分が検索対象に存在しなければ、MatchオブジェクトのSuccessプロパティがfalseとなる。
2番目にマッチした部分は、このようにして得られたMatchオブジェクトに対してNextMatchメソッドを呼び出して取得する。
m = m.NextMatch();
m = m.NextMatch()
この場合にもSuccessプロパティにより、マッチした部分が存在するかどうかをチェックする必要がある。以降は芋づる式にNextMatchメソッドを呼び出していけば、すべてのマッチした部分を順に得ることができる。
Matchオブジェクトは正規表現にマッチした部分文字列全体を保持しているが、正規表現にてグループ化を行っている場合には、その文字列からグループ化した部分のみを取り出すことができる。
これには次のようにしてMatchオブジェクトのGroupsプロパティでグループ名を指定し、そのValueプロパティにアクセスする。
string url = m.Groups["url"].Value;
string text = m.Groups["text"].Value;
Dim url As String = m.Groups("url").Value
Dim text As String = m.Groups("text").Value
正規表現内でグループに名前を付けていない場合には、自動的に振られる番号によりGroupsプロパティにアクセスすることになるが、このように名前を付けた方がコードは読みやすくなる。
以上をまとめたサンプル・プログラムを次に示す。
このサンプル・プログラムでは、@ITのトップページ(index.html)を読み込み、そのHTMLからアンカー要素に含まれるURL部分とリンク文字列部分を抜き出して表示する。
// regexmatch.cs
using System;
using System.Net;
using System.Text.RegularExpressions;
class RegexMatch {
static void Main() {
string anchor =
"<a href=\"(?<url>.*?)\".*?>(?<text>.*?)</a>";
// @ITのトップページを取得
WebClient wc = new WebClient();
string html = wc.DownloadString("http://atmarkit.itmedia.co.jp/");
Regex re = new Regex(anchor, RegexOptions.IgnoreCase
| RegexOptions.Singleline);
for (Match m = re.Match(html); m.Success; m = m.NextMatch()) {
string url = m.Groups["url"].Value;
string text = m.Groups["text"].Value;
Console.WriteLine(url);
Console.WriteLine(text);
}
}
}
// コンパイル方法:csc regexmatch.cs
' regexmatch.vb
Imports System
Imports System.Net
Imports System.Text.RegularExpressions
Class RegexMatch
Shared Sub Main()
Dim anchor As String = _
"<a href=""(?<url>.*?)"".*?>(?<text>.*?)</a>"
' @ITのトップページを取得
Dim wc As New WebClient()
Dim html As String = wc.DownloadString( _
"http://atmarkit.itmedia.co.jp/")
Dim re As = New Regex(anchor, RegexOptions.IgnoreCase _
Or RegexOptions.Singleline)
Dim m As Match = re.Match(html)
While m.Success
Dim url As String = m.Groups("url").Value
Dim text As String = m.Groups("text").Value
Console.WriteLine(url)
Console.WriteLine(text)
m = m.NextMatch()
End While
End Sub
End Class
' コンパイル方法:vbc regexmatch.vb
なお、このサンプル・プログラムにより得られるリンク文字列部分は、改行が含まれていたり画像タグ(<img>タグ)のみであったりする場合があるので、実際にリンク一覧などを作成したいときにはさらに加工が必要となる。
カテゴリ:クラス・ライブラリ 処理対象:文字列
使用ライブラリ:Regexクラス(System.Text.RegularExpressions名前空間)
使用ライブラリ:RegexOptions列挙体(System.Text.RegularExpressions名前空間)
使用ライブラリ:Matchクラス(System.Text.RegularExpressions名前空間)
Copyright© Digital Advantage Corp. All Rights Reserved.