おすすめ記事ピックアップ
PHPの文字を一括置換するstr_replace / preg_replaceで文字の置き換えしました。しかし正常に置換されません。うまく置き換えされず、かなり悩みました。原因は、重複置換されてしまうことでした。strtrで解決できました。すっきりした解決策がなかなか見つからなかったので、記載します。
またstr_replace / preg_replace / strtr の使い方の違いが分かりにくく、同じコードの比較の情報が無かったので、ついでに説明します。まずテキストで重複置換の問題をざっくり説明して、そのあとコードの説明をしたいと思います。strtr / str_replace / preg_replace の違いで1日悩んだので、誰かの参考になれば幸いです。
これは処理が一つ一つ行われるため、まず「AB」のAがABになり、「ABB」として次の処理に移ります。「ABB」のBがBCになるため、結果として「ABCBC」となってしまいます。
コード全体の説明としまして、form actionの<?php echo $_SERVER['SCRIPT_NAME'] ?>は、フォームと同一ファイルでPHPを実行するときの決まり文句です。テキストエリアには元からABのテキストを入れています。nameはtext1にしています。POSTで受け取ったtext1(つまりAB)を、$stringという変数に入れています。変更したい対象のテキストを$searchとして、置き換えるテキストを$replaceにしています。その1からその5まで、分かり易くするため、同じ変数名を使っています。echo で変更結果を出力しています。
echo str_replace($search,$replace,$string); としていますが、$text = str_replace($search,$replace,$string);として結果を変数に入れてから、echo $text;しても良いと思いますが、複雑に見えるかなと思い、そのままechoにしました。帰って分かりにくいかもしれませんけども。
preg_replace(①,②,③)、③の①を②に書き換えるというもので、str_replaceと一緒です。ただ①の部分にスラッシュで挟む違いがあるようです。('A','B')を('/A/','/B/')します。あとは一緒でした。
結果として「ABCBC」となってしまいます。要は同じで、一つ一つ処理されるからです。あーなってこーなるからです。
(実は、どの順番でどうなると、そうなるのか考えたのですがわかりませんでした。結果として駄目でした。)
うーん。分かり易く説明しようと思ったら、ながながと、ボケた文章になりました。こういった物の説明って難しいですね。
またstr_replace / preg_replace / strtr の使い方の違いが分かりにくく、同じコードの比較の情報が無かったので、ついでに説明します。まずテキストで重複置換の問題をざっくり説明して、そのあとコードの説明をしたいと思います。strtr / str_replace / preg_replace の違いで1日悩んだので、誰かの参考になれば幸いです。
str_replaceで置換がうまく行かない理由
初めにstr_replaceで置換を行いました。複数の置換がうまく行かなかった理由は、置換された文字が再び置換されてしまうことでした。例えば、「AB」のAをABに、BをBCにしたいとします。「AB」が「ABBC」になれば、正しい変換なのですが、str_replaceで置換すると「AB」が「ABCBC」になってしまいます。これは処理が一つ一つ行われるため、まず「AB」のAがABになり、「ABB」として次の処理に移ります。「ABB」のBがBCになるため、結果として「ABCBC」となってしまいます。
preg_replaceでも、結果は同じ
調べている途中にpreg_replaceなら重複されずに処理できるというテキストを見つけたのですが、結果は同じでした。preg_replaceでも「ABCBC」となります。また調べて行くうちに、処理されるarrayの順番を変えることで、重複を回避できるというテキストがあったのですが、こちらも順番が変わるだけで、同じ問題を持っています。strtrで解決
strtrなら重複されずに処理できました。str_replaceやpreg_replaceと使い方が少し違いまして、なかなか理解できませんでした。連想配列を使うのですが、なんでキーに設定するんだろうと、それがなかなか理解できず、意味が分からなかったのが原因です。自分の脳ミソが足らずでした。単純に変更したいテキストを入れれば、良いんだなと理解したら簡単でした。これで「ABBC」で変換できました。コードの説明
php全文記載します。長ったらしいですね。個別に説明すると余計複雑になりそうで、どうもすいません。phpファイルに張り付けて実行するとこのようになります。コード全体の説明としまして、form actionの<?php echo $_SERVER['SCRIPT_NAME'] ?>は、フォームと同一ファイルでPHPを実行するときの決まり文句です。テキストエリアには元からABのテキストを入れています。nameはtext1にしています。POSTで受け取ったtext1(つまりAB)を、$stringという変数に入れています。変更したい対象のテキストを$searchとして、置き換えるテキストを$replaceにしています。その1からその5まで、分かり易くするため、同じ変数名を使っています。echo で変更結果を出力しています。
echo str_replace($search,$replace,$string); としていますが、$text = str_replace($search,$replace,$string);として結果を変数に入れてから、echo $text;しても良いと思いますが、複雑に見えるかなと思い、そのままechoにしました。帰って分かりにくいかもしれませんけども。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>コード変換</title>
</head>
<body>
<!-- formn area-->
<form action="<?php echo $_SERVER['SCRIPT_NAME'] ?>" method="POST" >
<textarea name="text1" rows="6" cols="50">AB</textarea>
<br>
<input type="submit" class="button" value="変換する">
</form>
<br><br>
■その1:str_replaceでABを変換した場合<br>
<?php
$string = $_POST['text1'];
$search = array('A','B');
$replace = array('AB','BC');
echo str_replace($search,$replace,$string);
?>
<br><br>
■その2:preg_replaceでABを変換した場合<br>
<?php
$string = $_POST['text1'];
$search = array('/A/','/B/');
$replace = array('AB','BC');
echo preg_replace($search,$replace,$string);
?>
<br><br>
■その3:preg_replaceでarrayの処理順番を変えてABを変換した場合<br>
<?php
$string = $_POST['text1'];
$search = array('/A/','/B/');
$replace = array();
$replace[1] = 'BC';
$replace[0] = 'AB';
echo preg_replace($search,$replace,$string);
?>
<br><br>
■その4:strtrでABを変換した場合<br>
<?php
$string= $_POST['text1'];
$replace = array("A"=>"AB","B"=>"BC");
echo strtr($string, $replace);
?>
<br><br>
■その5:strtrのおまけ<br>
<?php
$string= $_POST['text1'];
echo strtr($string,"B","AB");
?>
</body>
</html>
その1:str_replaceでABを変換した場合の説明
str_replaceの説明ですが、str_replace(①,②,③)、③の①を②に書き換えるというものです。下記のように記述すると、文字の中も、AをABに、BをBCに書き換えしてくれます。しかし処理が一つ一つ行われるため、まず「AB」のAがABになり、「ABB」として次の処理に移ります。「ABB」のBがBCになるため、結果として「ABCBC」となってしまいます。■その1:str_replaceでABを変換した場合<br>
<?php
$string = $_POST['text1'];
$search = array('A','B');
$replace = array('AB','BC');
echo str_replace($search,$replace,$string);
?>
その2:preg_replaceでABを変換した場合の説明
preg_replaceは正規表現検索および置換を行う時に利用します。preg_replaceなら重複変換されないと記載あったので使ってみました。しかし重複変換されました。結果として「ABCBC」となってしまいます。ついでにstr_replaceとの書き方の違いの説明をします。preg_replace(①,②,③)、③の①を②に書き換えるというもので、str_replaceと一緒です。ただ①の部分にスラッシュで挟む違いがあるようです。('A','B')を('/A/','/B/')します。あとは一緒でした。
■その2:preg_replaceでABを変換した場合<br>
<?php
$string = $_POST['text1'];
$search = array('/A/','/B/');
$replace = array('AB','BC');
echo preg_replace($search,$replace,$string);
?>
その3:preg_replaceでarrayの処理順番を変えてABを変換した場合の説明
$replace部分の順番を逆にすれば、重複処理が解決できるという記述もあったのですが、こちらもできませんでした。結果として「ABCBC」となってしまいます。要は同じで、一つ一つ処理されるからです。あーなってこーなるからです。
(実は、どの順番でどうなると、そうなるのか考えたのですがわかりませんでした。結果として駄目でした。)
■その3:preg_replaceでarrayの処理順番を変えてABを変換した場合<br>
<?php
$string = $_POST['text1'];
$search = array('/A/','/B/');
$replace = array();
$replace[1] = 'BC';
$replace[0] = 'AB';
echo preg_replace($search,$replace,$string);
?>
その4:strtrでABを変換した場合の説明
strtrの使い方ですが、変換したい文字の数が異なる場合、連想配列を使う必要があるそうです。キーとして数値を入れて、そうやって利用するんだろうとか、難しく考えず、A=>ABにするという感じと考えたら楽になりました。下記のようにしたら「ABBC」と重複した置換も無く変換されました。■その4:strtrでABを変換した場合<br>
<?php
$string= $_POST['text1'];
$replace = array("A"=>"AB","B"=>"BC");
echo strtr($string, $replace);
?>
その5:strtrのおまけ説明
連想配列を利用しないと、BをABにしたくても、BはABにならず、Aになってしまいます。<br><br>
■その5:strtrのおまけ<br>
<?php
$string= $_POST['text1'];
echo strtr($string,"B","AB");
?>
</body>
</html>
うーん。分かり易く説明しようと思ったら、ながながと、ボケた文章になりました。こういった物の説明って難しいですね。