Perlの正規表現を用いた置換

文:Nick Gibson(Builder AU)
翻訳校正:村上雅章・野崎裕子
2007/12/27 08:00

Perlの正規表現のなかでも特に有益であり、かつ多用される置換や変換について解説する。

 grepは、正規表現を用いてテキストファイルを検索するための非常に手軽なユーティリティであるものの、そのシンタックスは、Perlで使用されているものと100%等しいというわけではないことに注意されたい。grepの詳細については、シェルから"man grep"と入力し、そのマニュアルページを参照してほしい。

 静的なテキストを完全に異なるテキストで置き換えるのではなく、ある行を少しだけ変更したいというケースは多いはずだ。その際に最もよく採られる方法の1つが、置換式内でのグループ化である。前回の記事では、括弧で囲んだ部分式同士を結合する例を示した。例えば以下の式では、行頭にあるハイフン、または1つ以上の空白文字(タブ文字を含む)が単一のタブ文字で置き換えられる。

$string =~ s/(^-)|([ \t]+)/\t/g;

 グループ化のもう1つのメリットとして、置換におけるマッチ式内でグループ化を行うことで、マッチした文字群を挿入できるようになるということがある。Perlでは、正規表現中の各グループにマッチした内容が$1〜$n(nは正規表現中のグループを示す連番)という変数に自動的に格納される。ここで、Builder AUサイトが古い記事を変換するために実際に使用している正規表現を例として以下に挙げたい。これは、古いスタイルの<br>という改行を<p>と</p>で囲まれたパラグラフに変換するというものである。

$string =~ s/^(.+)<br/?>/<p>$1<\/p>/g;

 同様に、CSV形式のファイル(変数がコンマで区切られている)は、以下のような正規表現を用いることで簡単にHTMLテーブルに変換することができる。

$string =~ s/([^,]+)[,\n]/<td>$1<\/td>/g;
$string =~ s/^(.+)$/<tr>$1<\/tr>/g;

 こういった例はいずれも完璧ではないものの、brタグをpタグに変換している例には特に、本質的な欠陥がある。これは、Perlの入力となる対象のHTMLには大文字と小文字が混在しているかもしれない一方、正規表現はデフォルトでは大文字と小文字を区別するためである。パターン修飾子を用いることで、正規表現において大文字と小文字を区別しないようPerlに指示することができる。ここまでで既に、"g"という修飾子を用いることでPerlに対してグローバルなマッチを指示している。同じようにして、大文字と小文字を区別しないという指示を以下のように記述することができる。

$string =~ s/^(.+)<br\/?>/<p>$1<\/p>/gi;

 これで、動作は前と同じだが、BRやBrでもマッチするようになった。この他に重宝しそうなパターン修飾子を4つ、以下に挙げたい。

  • m: 文字列を、改行コードが埋め込まれた単一の文字列としてではなく、複数の行として扱う
  • o: 包含されている変数の状態にかかわらず、式を1度だけコンパイルする
  • s: 文字列を単一行として扱う
  • x: 正規表現の拡張シンタックスを使用する。つまり、エスケープされていない空白文字はすべて無視され、正規表現を複数行に分割することができる。これによって、より複雑な表現をより読みやすい形式で記述し、コメントを挿入することもできるようになる。

 brタグをpタグに変換している例を用いて、拡張シンタックスを簡単に説明したい。

$string =~ s/^	(?# From the beginning of the line)
    (.+)	(?# Match more than one character)
    <br\/?>	(?# Then a break tag, with optional closing \/)
    /<p>$1<\/p>/gix;

 これは同じ意味を持っているが、マッチパターンが3行に分割され、各行の終わりには3つのマッチ部分に対するコメントが付加されている。拡張正規表現におけるコメントは(?#と)の内側に記述される。この例では大した内容になっていないものの、より長くて複雑な式では正規表現の可読性を大幅に向上させることができるのだ。

 これで置換はあなたの武器となり、使う準備が整ったことになる。そしてテキストを扱う際には、ちょっとした正規表現がさまざまな局面で役に立つと実感できるはずだ。さらに数カ月もすると、これまで正規表現を使用せずにやってこれたことが不思議に思えてくるだろう。

この記事は海外CNET Networks発のニュースをシーネットネットワークスジャパン編集部が日本向けに編集したものです。海外CNET Networksの記事へ

記事の感想やご意見をコメントでお寄せください(CNET_IDログインが必要です)
ログイン パスワードを忘れた方  |  新規登録
  • 今日のトップ記事
  • 昨日
  • 2日前
  • 5日前
  • 6日前
  • 7日前
  • 新着記事
  • 人気記事
  • 特集
  • ブログ