文字列の置き換え関数
はじめに
今回はPHPでちょっと複雑なプログラミングをするようになると出会う「str_replace」と「preg_replace」についてです。どちらもPHPの関数で、「str_replace」と「preg_replace」の使い方についてメモを残しておこうと思います。
str_replaceとpreg_replaceの特徴
「str_replace」と「preg_replace」はどちらも文字列を書き換えするために使われます。「私は運転が好きです」というテキストを「私は助手席が好きです」にしたり、「私は運転が嫌いです」にしたり、「俺ほど車を愛してる者はいない」のようにすべて置換することもできます。両者の違いに関して一言で言うと「正規表現を使うかどうか」になりますが、これは後述するので詳細はここでは割愛します。とりあえずどちらも「文字列を書き換えるもの」と理解しておいてください。
str_replaceの使い方
str_replaceの基本的な形はこのようになります。
str_replace(‘置換対象の文字列’, ‘置換後の文字列’, ‘置換対象の文字列が含まれている文字列’);
$subject = ‘私は運転が好きです’;
$search = ‘運転’;
$replace = ‘助手席’;
$subject = str_replace($search, $replace, $subject);
echo $subject;
//実行結果:私は助手席が好きです
このコードでは「運転」という文字列を対象にして「助手席」へ置換を実行しています。
preg_replaceの使い方
preg_replaceの基本的な形はこのようになります。
preg_replace(‘/置換対象の文字列/’, ‘置換後の文字列’, ‘置換対象の文字列が含まれている文字列’);
str_replaceと形はほぼ同じです。
$subject = ‘私は運転が好きです’;
$search = ‘/運転/’;
$replace = ‘助手席’;
$subject = preg_replace($search, $replace, $subject);
echo $subject;
//実行結果:私は助手席が好きです
str_replaceとの違い
では、str_replaceとの違いは何なのかというと、「正規表現」を使うかどうかです。
「正規表現って何?」という疑問もあると思いますが、preg_replaceにおける正規表現は「複雑な検索システム」としておくと理解しやすいと思います。
str_replaceでは単純な置換しかできませんが、preg_replaceではstr_replaceでは対応できない置換が可能です。
$subject = ‘<h1>私は運転が好きです</h1>’;
$search = ‘/<h1>(.*?)<\/h1>/’;
$replace = ‘<h2>$1</h2>’;
$subject = preg_replace($search, $replace, $subject);
echo $subject;
//実行結果:<h2>私は運転が好きです</h2>
このコードでは<h1>タグを<h2>タグに置換しています。
一気に難しくなった感じがしますが、難しく感じるだけで実はそこまで難しいことをしているわけではありません。
preg_replaceを理解する簡単な方法
・何かの文字列を囲んでいるタグを置換・除去したり、idやクラスを付与する
・何かの文字列を抜き出して別の形に変換する
preg_replaceを使うのはこのようなケースです。
重要なのは「検索する形」であり、それだけ覚えておけばpreg_replaceは怖くありません。
先述のコードだと以下の部分がそれに当たります。
$search = ‘/<h1>(.*?)<\/h1>/’;
これは<h1>タグで囲まれている部分を探すという意味ですが、それぞれ分解して解説します。
両側にスラッシュが必要
まず覚えることは、検索する文字列の両側にスラッシュが必要だということです。
検索パターン
最も重要なのがこの検索パターン。
先述のコードだと(.*?)がそれに当たります。
正規表現におけるカッコは「グループ化」を意味し、簡単に言うとその文字列を対象に何かの処理をするということになります。
$search = ‘/<h1>()<\/h1>/’;
<h1>タグで囲まれている文字列が対象になっているのがわかりますね。
また、以下の形だと<h1>タグの中の文字列の他に、idとクラスも対象にして何かをしたいということがわかるかと思います。
$search = ‘/<h1 id=”()” class=”()”>()<\/h1>/’;
これがグループ化です。
そして、このグループ化した文字列をどうやって検索するのかをカッコの中に記述します。
これがいわゆる「正規表現」と呼ばれるものです。
正規表現について
正規表現はググれば一覧が出てくるので覚える必要はありません。
例えば、先述の.*?の意味を平たく言うと「改行を除く任意の文字列」になります。
組み合わせているのは以下の3つ。
正規表現の文字 意味
「.(ドット)」 改行を除く任意の 1 文字
「*(アスタリスク)」 直前のサブ式と 0 回以上一致
「?(はてな)」 *や+などの修飾子の直後に指定するとできるだけ少ない文字列と一致
エスケープ処理
str_replaceになかったのがこのエスケープ処理です。
これも正規表現と同じく、エスケープ対象の文字(メタキャラクタ)とエスケープのやり方がググれば一覧で見れるので覚える必要はありません。
タグやURLで使われる「スラッシュ」もエスケープ対象なので、まずはそれだけ覚えておけばOKです。
例えば、「https://exsample.net」をエスケープ処理すると以下のようになります。
https:\/\/exsample\.net
基本的にはバックスラッシュ「\」を前に付けるだけです。
置換後の文字列
最後は置換後の形についてですが、覚えることは一つだけです。
それはグループ化した文字列を「$」+「数字」で呼び出せることです。
$search = ‘/<h1 id=”(.*?)” class=”(.*?)”>(.*?)<\/h1>/’;
この場合、グループ化している部分が3つあります。
左から順番に$1、$2、$3となり、$1はid、$2はclass、$3は<h1>タグの中の文字列になります。
これを使って例えばidとclassを逆にするには以下のようなコードになります。
$subject = ‘<h1 id=”h1-id” class=”h1-class”>これはh1タグの中の文字列です</h1>’;
$search = ‘/<h1 id=”(.*?)” class=”(.*?)”>(.*?)<\/h1>/’;
$replace = ‘<h1 id=”$2″ class=”$1″>$3</h1>’;
$subject = str_replace($search, $replace, $subject);
echo $subject;
//実行結果:<h1 id=”h1-class” class=”h1-id”>これはh1タグの中の文字列です</h1>
おわりに
正規表現はギターで言うところの「Fの壁」のような感じです。
コードを書いている内に慣れるので、まずは「形」を覚えれば十分でしょう。