1. 導入
Web開発の現場において、PDF生成やテキストメール、あるいはCLIツールを作成する際、「データの整形」は避けて通れない課題です。特に日本語を含む文字列を扱う場合、文字幅の計算やレイアウト崩れに悩まされることも少なくありません。また、セキュリティの観点から eval() を避けた数式評価や、入力値の妥当性を検証するためのチェックサムの実装など、アルゴリズムの知識はエンジニアの武器となります。今回は、実務で役立つ「テキスト整形の技術」と「アルゴリズムの実装」について解説します。
2. 基礎知識
今回扱う技術は主に2点です。
まず「文字列の整形」については、マルチバイト文字(日本語)の文字幅を考慮した制御が必要です。PHPの mb_strwidth() を使うことで、半角・全角を考慮した正確な表示幅を取得できます。
次に「逆ポーランド記法(RPN)」です。これは演算子をオペランドの後ろに置く表記法で、括弧を使わずに計算順序を定義できるため、計算機の内部処理として非常に効率的です。また「Luhnアルゴリズム」は、クレジットカード番号などの識別番号の誤り検出に広く使われているチェックサム手法です。
3. 実装/解決策
テキストを左右に分割して等幅で表示する場合、文字列を適切な長さで改行(breakString)し、各行の文字幅を計算してスペースでパディング(詰め物)を行うことで実現します。
数式処理については、toRpn() 関数で中置記法から逆ポーランド記法へ変換し、calcRpn() でスタックアルゴリズムを用いて計算を実行します。これにより、危険な関数を避けつつ安全な計算処理が可能です。
4. サンプルプログラム
以下は、文字列の左右整形を行うサンプルです。
/
function textTable($text1, $text2, $length1, $length2, $spacing = ‘ ‘) {
// 文字列を指定幅で強制改行する処理(省略)
$lines1 = explode(PHP_EOL, wordwrap_multibyte($text1, $length1));
$lines2 = explode(PHP_EOL, wordwrap_multibyte($text2, $length2));
$maxLines = max(count($lines1), count($lines2));
$result = ”;
for ($i = 0; $i < $maxLines; $i++) { $l1 = $lines1[$i] ?? ''; $l2 = $lines2[$i] ?? ''; // 左右の余白を埋めて整形 $pad1 = str_repeat(' ', $length1 - mb_strwidth($l1)); $pad2 = str_repeat(' ', $length2 - mb_strwidth($l2)); $result .= $l1 . $pad1 . $spacing . $pad2 . $l2 . PHP_EOL; } return $result; } // 簡易的なマルチバイト対応wordwrap function wordwrap_multibyte($text, $width) { return mb_strimwidth($text, 0, $width, PHP_EOL, 'UTF-8'); } // 実行例 echo textTable('商品名', '価格', 12, 8); echo textTable('たまねぎ', '400円', 12, 8); ?>
5. 応用・注意点
現場でこれらの技術を実装する際の注意点をまとめます。
・文字コードの罠: mb_strwidth() を使用する際は、必ず mb_internal_encoding() が UTF-8 に設定されているか確認してください。
・セキュリティ: 数式を扱う際、今回は逆ポーランド記法を紹介しましたが、外部からの入力をそのまま処理する場合は、正規表現で「使用可能な文字(数字と演算子のみ)」をホワイトリスト方式で厳格にバリデーションすることを強く推奨します。
・パフォーマンス: 文字列操作やループ処理が多い場合、大量のデータを一度に処理するとメモリを消費します。必要に応じてジェネレータ(yield)を活用し、メモリ効率を高める設計を心がけましょう。