ちょっと複雑なプログラミングをするようになると出会う「str_replace」と「preg_replace」。
どちらもPHPの関数で、WordPressでテーマを自作していると頻繁に使うようになります。
ただ、以前ご紹介した「echo」や「return」などとはレベルが違うため、少し理解しづらいかもしれません。
そこで今回は「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の基本的な形はこのようになります。
preg_replace('/置換対象の文字列/', '置換後の文字列', '置換対象の文字列が含まれている部分');
はい、実はstr_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では対応できない置換が可能です。
サンプルコード
百聞は一見にしかずということで、preg_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>
タグで囲まれている部分を探すという意味ですが、それぞれ分解して解説します。
両側にスラッシュが必要
まず覚えて欲しいのは、検索する文字列の両側にスラッシュが必要だということです。
文字列なのでシングルクォーテーションは当然必要ですが、preg_replaceではそれに加えてスラッシュも必要です。
検索パターン
最も重要なのがこの検索パターン。
どうやって文字列を検索するかということです。
先述のコードだと(.*?)
がそれに当たります。
これはただのまとまりではなく、ちゃんと意味があります。
正規表現におけるカッコは「グループ化」を意味し、簡単に言うとその文字列を対象に何かの処理をするということになります。
先述のコードをこうしてみると理解しやすくなるかもしれません。
$search = '/<h1>()<\/h1>/';
<h1>
タグで囲まれている文字列が対象になっているのがわかりますね。
また、以下の形だと<h1>
タグの中の文字列の他に、idとクラスも対象にして何かをしたいということがわかるかと思います。
$search = '/<h1 id="()" class="()">()<\/h1>/';
これがグループ化ですね。
そして、このグループ化した文字列をどうやって検索するのかをカッコの中に記述します。
これがいわゆる「正規表現」と呼ばれるものです。
正規表現について
この正規表現はググれば一覧が出てくるので覚える必要はありませんし、ある程度決まった形があります。
例えば、先述の.*?
の意味を平たく言うと「改行を除く任意の文字列」になります。
組み合わせているのは以下の3つ。
正規表現の文字 | 意味 |
.(ドット) | 改行を除く任意の 1 文字 |
*(アスタリスク) | 直前のサブ式と 0 回以上一致 |
?(はてな) | *や+などの修飾子の直後に指定するとできるだけ少ない文字列と一致 |
他の文字や特殊文字(メタキャラクタ)については以下のページが参考になります。
参考正規表現あれこれ
エスケープ処理
str_replaceになかったのがこのエスケープ処理です。
これも正規表現と同じく、エスケープ対象の文字(メタキャラクタ)とエスケープのやり方が一覧で見れるので今覚える必要はありません。
タグやURLで使われる「スラッシュ」もエスケープ対象なので、まずはそれだけ覚えておけばOKです。
例えば、「https://fantastech.net」をエスケープ処理すると以下のようになります。
https:\/\/fantastech\.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の壁」です。
コードを書いている内に抵抗感はなくなるので、まずは「形」を覚えましょう。