.NET TIPS

正規表現を使って部分文字列を取得するには?[C#、VB]

デジタルアドバンテージ 遠藤 孝信
2007/04/05

 本稿では、ある文字列内から特定のパターンにマッチする部分文字列を抜き出す処理について、正規表現を使った場合の基本的な手順をまとめる。

 ここでは例として、HTMLから、

<a href="URL" ……>テキスト</a>

のような形式のアンカー要素に対して、URL部分とテキスト部分を取り出す場合を考えてみよう。

 このようなアンカー要素にマッチする正規表現は次のようになる。

<a href="(?<url>.*?)".*?>(?<text>.*?)</a>

 2個所ある「(」と「)」で囲まれた部分は「グループ化」を行っており、それぞれに対して「?<url>」「?<text>」により、「url」と「text」というグループ名を付けている。

 ちなみに「.*?>」の部分で使用している「?」は最短一致を指定するもので、「.*?>」は、「>」以外の任意の文字の並び+「>」、を表すことになる(「.*?)」の部分も同様)。

Regexオブジェクトの作成

 まず、上記の正規表現を表す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)
Regexオブジェクトの作成(上:C#、下:VB)

 ここでは第2パラメータで2つのオプションを指定している。RegexOptions.IgnoreCaseは大文字小文字を区別せずにマッチするためのものだ。これにより「<A HREF=……」のようなアンカー要素にもマッチするようになる。RegexOptions.Singlelineは任意の1文字を示す「.」を改行文字にもマッチさせるためのものだ。これにより1つのアンカー要素が複数行に渡って記述されていてもマッチするようになる。

Matchオブジェクトの取得

 次にマッチングを実行し、最初にマッチした部分をMatchクラス(System.Text.RegularExpressions名前空間)のオブジェクトとして取得する。これにはRegexオブジェクトのMatchメソッドを呼び出す。Matchメソッドのパラメータには、検索対象となるテキストを文字列で指定する(本稿の例ではHTMLの内容)。

Match m = reg.Match(<検索対象となる文字列>);
Dim m As Match = reg.Match(<検索対象となる文字列>)
Matchオブジェクトの取得(上:C#、下:VB)

 ただし、マッチする部分が検索対象に存在しなければ、MatchオブジェクトのSuccessプロパティがfalseとなる。

 2番目にマッチした部分は、このようにして得られたMatchオブジェクトに対してNextMatchメソッドを呼び出して取得する。

m = m.NextMatch();
m = m.NextMatch()
2番目にマッチした部分のMatchオブジェクトの取得(上:C#、下:VB)

 この場合にもSuccessプロパティにより、マッチした部分が存在するかどうかをチェックする必要がある。以降は芋づる式にNextMatchメソッドを呼び出していけば、すべてのマッチした部分を順に得ることができる。

Matchオブジェクトからグループ化した部分の取り出し

 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
2番目にマッチした部分のMatchオブジェクトの取得(上:C#、下:VB)

 正規表現内でグループに名前を付けていない場合には、自動的に振られる番号によりGroupsプロパティにアクセスすることになるが、このように名前を付けた方がコードは読みやすくなる。

HTMLからアンカー要素を抜き出すサンプル・プログラム

 以上をまとめたサンプル・プログラムを次に示す。

 このサンプル・プログラムでは、@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://www.atmarkit.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
HTMLからアンカー要素のURLとリンク文字列を抜き出すC#のサンプル・プログラム(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://www.atmarkit.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
HTMLからアンカー要素のURLとリンク文字列を抜き出すVBのサンプル・プログラム(regexmatch.vb)

 なお、このサンプル・プログラムにより得られるリンク文字列部分は、改行が含まれていたり画像タグ(<img>タグ)のみであったりする場合があるので、実際にリンク一覧などを作成したいときにはさらに加工が必要となる。End of Article

カテゴリ:クラス・ライブラリ 処理対象:文字列
使用ライブラリ:Regexクラス(System.Text.RegularExpressions名前空間)
使用ライブラリ:RegexOptions列挙体(System.Text.RegularExpressions名前空間)
使用ライブラリ:Matchクラス(System.Text.RegularExpressions名前空間)

この記事と関連性の高い別の.NET TIPS
正規表現を使って文字列から部分文字列を取り除くには?
正規表現を使ってパターンに一致する全ての文字列を抽出するには?[C#/VB]
全角英数字のみを半角に変換するには?
正規表現を使って文字列がパターンに一致するか調べるには?[C#/VB]
文字列のひらがな/カタカナをチェックするには?
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム Jigsaw(ジグソー) により自動抽出したものです。
generated by

「.NET TIPS」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)
- PR -

注目のテーマ

Insider.NET 記事ランキング

本日 月間
ソリューションFLASH