メモでっすぅ!
いつもの様に無駄長いので
面倒な方は
結果を言えば
から読んでね^x^;
ではどうぞ!
PHPでは"" と'' の違いは、"" だと変数などが中に書かれていると展開されるという扱い。
なのだけど、"/r/n"としたときと、'/r/n'とした時では挙動が違う
前者の"/r/n"は、文字コードで、確か「\r」はchr(13), 「\n」 => chr(10)
になってしまうんじゃないかな。
なので正規表現の中で"" を使っていて、しかも中でPHPが置き換える可能性のある文字は、
置き換えられてから関数で処理されてしまうから注意が必要
またこれはmysql やmyslqiの関数で、real_escape_string を使って
文字列を収納すると、「"」の方の"/r/n"、つまりchr(13)+chr(10)が、
普通の文字列の「'」の方の、'/r/n'になって保存されてしまう
文字列が二重引用符 (") で括られた場合の話は公式の
文字列 に話はある。
また、もしも上記のreal_escape_string(mysqli なら
mysqli:: real_ escape_string)
を使っちゃったら、
nl2br 関数を使って処理すればいいや!なんて思っていても、
nl2br は文字コードのchr(13)+chr(10)、つまり"" の方の"/r/n" を
文字列の'<br>' もしくは’<br />' に置き換える関数で、ただの文字列となってしまっている
'/r/n' は置き換えられない。
置き換えられないならば、ereg_replace か、preg_replace で置き換えようと
想像がついたので置き換えようとした訳で、このブログを書いている。
まず、置き換えようとする時、"/r" や"/n" や"/r/n" は上記の様に
制御コードとなってしまうしので" でなくて ' にするのは良いとしても
エスケープシーケンス という方法を使わなければいけなくなる。
理由は/ という記号自身が文字や文字列である理由から逸脱(エスケープ)して、
しまう為、これを回避する方法が公式ページ(その
エスケープシーケンス )には
注意:
シングルクォートあるいはダブルクォートで囲まれた PHP の 文字列 の中では、バックスラッシュは特別な意味を表します。 そのため、正規表現 \\ を使用して \ とマッチさせたい場合は PHP のコード内では "\\\\" あるいは '\\\\' と記述する必要があります。
と書いてある。
なので、よくサイトなどで、簡単な説明で
ereg_replace("\n|\r|\r\n","<br>",$string);
とかで動くんじゃ?と思ったけれど、これ動かなかった。
勿論正規表現をやめて
str_replace(array("\r\n","\n","\r"),$br,$string);
とすれば動いた、けれどせっかくなので
preg_replace で動かそうと思った。
よく考えても何処にも答えがニアピンで載ってなくてよく分からなかったのだけれど、
/ ではエスケープシーケンス動作なので、これを消すには// かなと思ったけど、
そうすると多分、エスケープシーケンスを消すので、それは無かった事とされてしまう??w
あ、偶数でないと困るのかな・・・・、前後に // と正規表現をするから・・・
確かに上記の□枠の解釈だと/// と3つつけることになり、意味はあってそう
なんか、意味が具体的に書いてないからなんとも・・・・・・
本当によくわかってないけど・・・・まぁ・・・・ なんかをキャンセルしてると理解しようorz
ここ重要かもしれないけど、エスケープシーケンスをエスケープするのは'//'を前にくっつける??
これ、公式マニュアルに書いてない!!!???
なので'/n' は'//'と'/n' をくっつけた'///n' でやっと文字列の「/n」を選んだ事になるみたい・・・
うーん、なんだか意味がわからないけど、これは公式の説明に載せて欲しいな・・・・
話は長くなったけれど、
結果を言えば
PHP の正規表現(preg_replace)で、改行を置き換えたい時は、
"/\r\n|\r|\n/"では動かないので、'/\\\r\\\n|\\\r|\\\n/'
にしなければいけない。
纏めると
改行を表すコードは
"/r" chr(13) これは'/r' ではない!
"/n" chr(10) これは'/n' ではない!
"/r/n" chr(13)+chr(10) これは'/r/n' ではない!
※chr(10) とかchr(13) は確か・・・ そうだったと思う、このブログを書いている最中は
確かめてません・w・;
また正規表現で
文字列の「/r」つまり'/r' を置き換えたい場合には、
エスケープシーケンスのエスケープをして
'///r' とする / は頭に2つ付けて // 合計3つで ///r となる。
同様に
/n => ///n
/r/n => ///r///n
となる。
これでOKみたい。
作った関数
//*********************************************************************************************************************************************************************************************************
// PHP の関数であるnl2br は文字コードの変換で、コードでなく文字に置き換えられた「\r(/r)」「\n(/n)」「\r\n(/r/n)」には使えないので、この関数で<br> もしくは、XHTML 準拠の <br /> に置き換える
function nl_string_2br($string,$is_xhtml=false){
if($is_xhtml==false){$br='<br />';}else{$br='<br>';}
// return str_replace(array("\\r\\n","\\n","\\r"),$br,$string);
return preg_replace('/\\\r\\\n|\\\r|\\\n/', $br, $string);
}
ネーミングセンスが微妙なので、使う場合には名前をつけなおそぅ(ぇ
あと、
// return str_replace(array("\\r\\n","\\n","\\r"),$br,$string);
return preg_replace('/\\\r\\\n|\\\r|\\\n/', $br, $string);
としてあるけど、str_replace が好みの人は
return str_replace(array("\\r\\n","\\n","\\r"),$br,$string);
// return preg_replace('/\\\r\\\n|\\\r|\\\n/', $br, $string);
としてね!
以上、長いメモでした<(_ _)>
追伸
公式マニュアルの
定義済みの定数 に
PHP_EOL
(string)このプラットフォームの行末文字。 PHP 4.3.10 および PHP 5.0.2 以降で利用可能。というのを見つけた。
プラットフォームによって変わるのかぁ・・・・・
うーん、フォームから入力、つまりブラウザから入力したって
プラットフォーム、つまりWebサーバーに依存するのかな
まぁいいや、どっちにしても/r と/n と/r/n 全てを処理した方が
無難そう。
コピペしたら多分、ブラウザからの入力に依存する気もする、
うん? やっぱブラウザの入力に依存するんじゃないか?v?
まぁ、いいや、多分そう使わないかな・・・・
サーバーの使う文字コードを調べるにしても、改行コードでは調べられないし。
一応追加のメモでしたぁ_(._.)_
追伸
先に書いた関数を使うより
// 文字コードでなく、文字として「\r(/r)」「\n(/n)」が存在する場合に、文字コードの改行に戻す
function br_string_2nl($string){
return str_replace(array('\r','\n'),array("\r","\n"),$string);
}
こちらの関数を良く使う様になった(というか、先に書いた関数は使わなくなった^^;)
コメント一覧