Tutorial
この記事の読了時間:約9分32秒
長文テキストから必要な文字列を抜き出したり、HTMLソースから欲しいトコを抽出したりしたい時、役に立つのが「正規表現」。
使えるようになるとメチャクチャ便利なんですが、記号の羅列っぷりに気押されして、初めはなかなか手をつけられないんですよねー。
自分自身まだまだヒヨッコではありますが、それでも「たったコレだけ知ってるだけでも、効率がガクンと上がったよ!」という正規表現について、ご紹介しちゃおーと思います。
サンプルは基本的にPHPのモノですが、内容はPerlでもテキストエディタの検索/置換機能でもおおよそ同じかと思いますので、そこら辺は各自で適宜読み替えつつ、ご覧になって下さいまし☆
正規表現自体イマイチ良く分からんって方のためにカンタンに説明すると、正規表現とは「あらかじめ決められた記号と文法を駆使して、文字列(文章)を抽象的に表現する方法」ってトコです。
この「抽象的に表現する」ってのがミソなんですが、コレは多分なんか例題があった方が分かりやすいと思うので、まずは下記をご覧下さいまし☆
まず最初に関数の説明をしちゃいます。
preg_replace関数は「ある文字列の中から、正規表現にマッチする部分を、別の文字列で置換する」関数で、preg_replace(正規表現のパターン, 置き代える文字列, 対象の文字列)って使い方をします。
preg_match関数は「ある文字列の中に、正規表現にマッチする部分があるか検索して、(必要なら)該当部分を抜き出しつつ、マッチした回数を返す」関数で、使い方は、preg_replace(正規表現のパターン, 対象の文字列, 抜き出した該当部分を代入する変数)って感じです。
それでは改めて。
$string_a = 'あいうえお12345abc'; $string_b = 'さしすせそ67890xyz'; $pattern_1 = '/うえお/'; $sample_1_a = preg_replace($pattern_1, 'してる', $string_a); $sample_1_b = preg_replace($pattern_1, 'してる', $string_b); echo $sample_1_a; // 結果:あいしてる12345abc echo $sample_1_b; // 結果:さしすせそ67890xyz $pattern_2 = '/[0-9]{5}/';//正規表現で「0から9までの数字、5ケタ」という意味 $sample_2_a = preg_replace($pattern_2, 'なー', $string_a); $sample_2_b = preg_replace($pattern_2, 'なー', $string_b); echo $sample_2_a; // 結果:あいうえおなーabc echo $sample_2_b; // 結果:さしすせそなーxyz $pattern_3 = '/^(.*)[0-9]{5}/';//何かしらの文字の後に「0から9までの数字、5ケタ」 preg_match($pattern_3, $string_a, $sample_3_a); preg_match($pattern_3, $string_b, $sample_3_b); echo $sample_3_a[1]; // 結果:あいうえお echo $sample_3_b[1]; // 結果:さしすせそ
最初の例($pattern_1の方)では、具体的に「うえお」という厳密な文字列を検索→置換してるので、「うえお」が入ってない$string_bの方は何も変化ありません。
しかし次の$pattern_2では、謎の記号(コレが「正規表現」!)をパターンとしており、その意味も「0から9までの数字、5ケタ」という抽象的なモノなので、両方の文字列ともに置換されたっちゅーワケです。
謎の記号の組み合わせ方によっては、「"http://"って文字から始まって、いくつかドットがあって、最後にhtmlで終わる」とか「<table id="xxx">と</table>の間」とかって意味付けも出来ちゃいます。
つまり、正規表現が使えると、長文テキストファイルの中の「株式会社 / 有限会社 / 合同会社 / 合資会社」を全て一括で「NPO法人」に書き換えたり、HTMLのソース内にある必要な情報だけを抜き出したり、そんなコトができちゃうんです!
やたら長くなっちゃいましたが、やっとこさ本題に行ってみよー!
むしろコレ1つだけでいいんじゃないか?ってくらい、便利な正規表現。
誤解を恐れぬカンタンな意味説明ですが、カッコ ドット コメ ハテナの意味を。
・カッコ = カッコ内の正規表現で抽出された文字列を、変数や保存領域に「一時保存させる」。
・ドット = 改行以外の全てを含む「1文字」。
・コメ = コメの直前に書かれた表現を「0回以上繰り返す」。
・ハテナ = (マッチする終点が複数ある場合)なるべく短いトコで止める。
$string_a = 'うはwwwおkwwwwでっていうwww'; $string_b = 'お前はもう、すでに、死んでいる!'; $pattern_1 = '/は(.*?)で/'; preg_match($pattern_1, $string_a, $sample_1_a); preg_match($pattern_1, $string_b, $sample_1_b); echo $sample_1_a[1].'<hr>'; // 結果:wwwおkwwww echo $sample_1_b[1].'<hr>'; // 結果:もう、す //ちなみに、カッコが無いと。。。 $pattern_2 = '/は.*?で/'; preg_match($pattern_2, $string_b, $sample_2_b); echo $sample_2_b[1].'<hr>'; // 結果:NULL //ちなみに、ハテナが無いと。。。 $pattern_2 = '/は(.*)で/'; preg_match($pattern_2, $string_b, $sample_2_b); echo $sample_2_b[1].'<hr>'; // 結果:もう、すでに、死ん
ちなみに、カッコで保持した文字列は、上記例のpreg_match関数では「第3引数で指定した変数名」の配列で保持されますが、さくらエディタとか秀丸エディタで置換する場合は「¥1」という名前で保持されます。
あと、正規表現の解説サイトなどでは、カッコのことを「グループ化する」とかって書いてありますが、それは今回の「保持する」って機能とは別の機能で、同じ記号ですがちょっと使い方が違いますのでご注意を。
「¥t」とは「タブ」のコトで、「¥n」とは「改行」のコトです。
$string_a = <<<str <div id="header"> <h1>天地爆烈(メガデス)!!!</h1> <h2>爆霊地獄(ベノン)!!</h2> <h3>爆炎障壁(ガンズン=ロウ)!</h3> </div> str; $pattern_1 = '/¥t/'; $sample_1 = preg_replace($pattern_1, '', $string_a); echo $sample_1.'<hr>'; //結果: /* <div id="header"> <h1>天地爆烈(メガデス)!!!</h1> <h2>爆霊地獄(ベノン)!!</h2> <h3>爆炎障壁(ガンズン=ロウ)!</h3> </div> */ $pattern_2 = '/¥n/'; $sample_2 = preg_replace($pattern_2, '', $string_a); echo $sample_2.'<hr>'; //結果: /* <div id="header"> <h1>天地爆烈(メガデス)!!!</h1> <h2>爆霊地獄(ベノン)!!</h2> <h3>爆炎障壁(ガンズン=ロウ)!</h3></div> */
この「¥」マークがポイントなんですが、これは「¥○」といった感じで、○のトコに特定の記号を記述することで特殊な意味を表したり、○のトコの記号が単なる文字列なのか、意味のある記号なのかを指定するのに使うマークで、いわゆる「エスケープシケンス」と呼ばれるシロモノです。
正規表現のエスケープシーケンスは、タブを表す「¥t」や改行を表す「¥n」の他、0から9の数字を表す「¥d」や、半角英数字とアンダーバーを合わせて表す「¥w」なんかもありますが、テキストの置換編集なんかなら上記の「¥t」と「¥n」を覚えときゃー何とかなるコトが多いはず!
ここまで読んで、正規表現に興味を持った方や、こんなアバウトじゃなくしっかりと勉強したいよママン!って方は、下記リンクをオススメします。
比較的初歩的な段階から解説されてたりするので、とても分かりやすく勉強になるんじゃないかなと思います☆
そのうち「コレを一発で抽出する書き方が出来たら、もっとラクなのになー。。。」ってゆーのが出てきたら、さらに成長のチャンス!
正規表現って要はパズルみたいなモンで、記号とその意味の組み合わせなので、一回覚えちゃえば後はラクチンですよー♪
関連する記事
同じカテゴリーの記事
smkn より:
2011/09/28 11:36 AM
> kenjis 様
ご教示ありがとうございます! i や s は使ってましたが、uは使ってなかったです。以後気をつけます!
記事に関しても、実は今回の記事で修飾子を扱うかどうか迷ったんですが、とりあえず正規表現への抵抗感がある方に、手始めのきっかけになれれば、という本題から考えると少し小難しくになっちゃう気がしたので、敢えて外しました。
ともあれ、教えてくださりありがとうございます!
kenjis より:
2011/09/28 10:40 AM
preg_* でマルチバイト文字を扱うには、文字コードがUTF-8で u 修飾子を付ける必要があります。そうでなければ、正しく処理できない場合があります。