PHP使って10年以上な訳だが、いまだにこんなことが起こるとは…orz

(PHPと正規表現とは直接的には関係ないけどね(*ノω・*)

読み込んだテキストファイルの文頭のヘッダ的な箇所を取り除こうとして、
preg_replace('/^.*----/s', '', $text);
とした(※)ところ、テキストファイルがSJISだったため文字化け。
あちゃー、と思いフツーにUTF-8に変換して再度実行。
すると…なぜか空文字列が返った。

正規表現が誤っているのかと試行錯誤してみるも、どうもうまくいかない。
半狂乱のなか(^o^;)、SJISのままpreg_replaceにかければうまくいくことに気付く。

んで、ググると、「mb_regex_encoding("UTF-8");」を使おう的なことが書いてあり、
狂喜乱舞しながら実行
 ↓
轟沈(´;ω;`)

さらにググる。全然違うネタなんだけど…
preg_matchの挙動がなんかへん、というか、PCREか? - uzullaがブログ
『u パターン指示子(utf-8指定のアレ)をはずしても動く』っとの記述が。
『utf-8指定のアレ』だとおぅっ!

半信半疑ながら、uフラグを追加してみると…うまくいく出羽内科っ!
preg_replace('/^.*----/su', '', $text);

うーむ、釈然とせぬ。
UTF-8なんて、PHPの使い始めこそまだ実用的ではなかったので使用してなかったが、ここ5年以上はほぼUTF-8を使ってきたのに…。
なぜ今までこの問題に突き当たらなかったのか?
正規表現で複数行だって扱ったはずなんだけどなぁ…。

ま、解決できたから良しとしよう。
まだまだ前に進まねばならぬのだから。


※: sフラグ(※2)で複数行を一行として処理、行頭からハイフンが4つ繰り返すところまでを取り除く。
ネタバラシすると、青空文庫のテキストファイルです。
文頭に記号についての解説があり、ハイフン×55字で仕切られているので、このようにした。

※2: PHPマニュアルでは「パターン修飾子」と呼ばれているみたい。


↓意味は無いと思うが、PHPマニュアルから抜粋しておく。

・u (PCRE_UTF8)
この修正子は、Perl 非互換な PCRE の機能を有効にします。パターンと対象文字列は、 UTF-8 として処理されます。 この修正子は、UNIX では PHP 4.1.0 以降、Win32 では PHP 4.2.3 以降で 使用可能です。 また、PHP 4.3.5 以降では、パターンの UTF-8 としての妥当性も確認されます。 無効な対象文字列を preg_* 関数に渡しても、何もマッチしません。 無効なパターンを渡すと、E_WARNING レベルのエラーが発生します。 5オクテットおよび6オクテットの UTF-8 シーケンスは、PHP 5.3.4 以降 (PCRE 7.3 2007-08-28 以降) では無効とみなされます。 以前のバージョンでは、これらも UTF-8 として有効だとみなされていました。



[追記]
改行コードがらみで。
mフラグを付けて複数行モードにした場合、行末に"$"がマッチするハズが、してくれない。
と思ったら、どうやら改行コードが「\r\n」(CR+LF)だとダメみたい。
$text = str_replace("\r", "", $text);
として改行コードを「\n」のみにしたら意図通りに動いた。