Upgrade to Pro — share decks privately, control downloads, hide ads and more …

mb_trim関数を作りました

 mb_trim関数を作りました

PHPカンファレンス香川の資料です #phpconkagawa

てきめん tekimen

May 11, 2024
Tweet

More Decks by てきめん tekimen

Other Decks in Programming

Transcript

  1. 自己紹介 てきめん • https://tekitoh-memdhoi.info • X: @youkidearitai • https://github.com/youkideari tai

    • PHP 8.4で複数の関数を作った – mb_trim – mb_ucfirst、mb_lcfirst – grapheme_str_split オレ
  2. RFCを記述するWiki Karma Request • RFCを記述するのが初めてだったので、まずアカウントを作り ます • アカウントを作ったら、Internalsメーリングリストへ「RFC Karma Request」を投げます

    – タイトルはこのままで「〇〇したいです」を添えれば大体許可さ れます – 許可されたらWikiの編集権をもらえます
  3. Optimizations for mb_trim #12803 • nielsdosさんがmb_trim 関数のパフォーマンス調 整をしてくれて、 4文字 (コードポイント)までは線

    形探索したほうが速いとわ かった – O(1)が0個でも1回計算し なきゃならないところもあり うる
  4. Build failed at mbstring_arginfo.h on Windows(Visual C++) #13789 • Windowsの日本語のVisual

    C++でビルドができないという 問題を(あの)廣川さんから メールでもらう – $charactersをUTF-8バイト列 でコンパイルしていたのが問 題 – コンパイル時のフラグにUTF- 8であることを加えることで対 処
  5. mb_trim() inaccurate $characters default value #13815 • mb_trim関数群で文字コードが UTF-8じゃないときにtrimしない というIssue

    – inaccurateが「正しくない」なの で、最初なんのことかわからな かった… – 結局、$charactersを決め打ちし てるのがよくないので、NULLが 正しいのでは?となる
  6. Fix GH-13815: mb_trim() inaccurate $characters default value #13820 • nielsdosさんによるプルリク

    エスト – $charactersをNULLにしま しょうというプルリクエスト – ただし、RFCの内容を書き換 えるためPHP Internalsで議 論する必要になり議論を行っ た
  7. 使い方 • mb_[lr]?trim関数はいわゆる全角スペース(U+3000)もtrimできます – PCREで言うところの\sなどをサポートしています • ユースケースの一つとして、mb_ltrim関数を使ってUTF-8 BOMを削除できます – mb_ltrim($str,

    “\u{FEFF}”); • 例えばmb_substrでZero Width Joiner(ZWJ)を含む絵文字などでZWJが残ったと き、mb_rtrim関数を使ってZWJを削除できます – mb_substr(mb_rtrim(“ ”, “\u{200D}”), 0, 2); 🙇‍♂️ • 複数の文字(コードポイント)にも対応してます – mb_trim($str, “ \n\r\u{200D}\u{FEFF}”); • もちろん、他の文字エンコーディングにも対応しています – mb_trim($str, encoding: “shift_JIS”); • マニュアルはPHP 8.4に合わせて書き出すと思います
  8. Appendix: mb_trimのアルゴリズム • 1コードポイントごとに左から右へ処理をしていく • 128コードポイントごとにto_wcharメソッドが呼び出される • 左側にtrimする文字があればleftを1足す • 左側のtrimする文字がなければ右側のtrimに移るため、フラグを

    rightへの処理にするため、XORでMB_RTRIMに変更 • 右側にtrimする文字があればrightを1足す • 右側にtrimする文字がなければrightを0にリセット • 下記のような擬似コードでmb_substrする: – mb_substr($str, left, mb_strlen($str) – (right + left));