preg_replace("/正規表現/", 置き換え文字列, 対象文字列)
置き換え文字列には、$1や$2、\1や\2などを使うことができます。$1と\1は、同じ意味で、$2と\2も同じ意味で、正規表現のパターンと一致した文字列を分けて扱うことができます。$のほうが推奨されており、${1}もいいです。
/(スラッシュ)には特別な意味がなく、正規表現のパターンの範囲を表しており、スラッシュを使うことが多いですが、何の文字でもいいです。
$1・\1例
$beforeText = 'apple:banana:lemon:3つで、100000000円します。';
$afterText = preg_replace("/(apple)/", '$1[りんご]', $beforeText);
------結果---------
"apple[りんご]:banana:lemon:3つで、100000000円します。"
appleという文字列の後ろに、日本語訳をつけてみました。\1を使います。
$beforeText = 'apple:banana:lemon:3つで、100000000円します。';
$afterText = preg_replace("/(apple)/", '\1[りんご]', $beforeText);
------結果---------
"apple[りんご]:banana:lemon:3つで、100000000円します。"
同様の結果が得られました。それでは、$1と$2と$3を使ってみましょう。
$1・$2・$3例
$beforeText = 'apple:banana:lemon:3つで、100000000円します。';
$afterText = preg_replace("/(apple)(:)(banana)/", '$1[りんご]$2$2$2$2$3[ばなな]', $beforeText);
------結果---------
"apple[りんご]::::banana[ばなな]:lemon:3つで、100000000円します。"
一致する文字列は、「apple:banana」を探すことにしました。そのうえで、一致した場合にその文字列を分けて、扱いたかったため、「(apple)(:)(banana)」としました。そして、置換後の文字列では、分けた効果を使用しています。
後読み先読み
パターン | 解説 |
---|---|
肯定的先読み(?=文字列) | apple(?=banana) 直後にbananaがあるappleのみに一致 |
否定的先読み(?!文字列) | apple(?!banana) 直後にbananaがないappleのみに一致 |
肯定的後読み(?<=文字列) | apple(?<=banana) 直前にbananaがあるappleのみに一致 |
否定的後読み(?<!文字列) | apple(?<!banana)直前にbananaがないappleのみに一致 |
さっそく肯定的先読みを使ってみましょう。
$beforeText = 'apple:banana:lemon:3つで、100000000円します。apple';
$afterText = preg_replace("/(apple)(?=:banana)/", '$1[りんご]', $beforeText);
------結果---------
"apple[りんご]:banana:lemon:3つで、100000000円します。apple"
後ろが「:banana」がある場合の、appleのみ置換しています。
正規表現後読み先読み参考にさせていただいた記事
数字を3桁ずつで,で区切る
$beforeText = 'apple:banana:lemon:3つで、100000000円します。apple';
$afterText = preg_replace("/(\d)(?=(\d{3})+(?!\d))/", '$1,', $beforeText);
------結果---------
"apple:banana:lemon:3つで、100,000,000円します。apple"
正規表現のパターンの説明をします。
・「(\d)」は、半角数字
・「?=(\d{3})」半角数字の直後に、半角数字が3つ続いたもの(肯定的先読み)
・「(?!\d)」は、半角数字が3つ続いたものを1回以上繰り返した文字の直後に、半角数字じゃないもの(否定的先読み)
つまり、半角数字の直後に、半角数字が3つ(1回以上)続き、その直後は、半角数字じゃないものがあれば、「,」を足す。
「100000000円」->「100,000,000円」