PHPでメルマガ用の原稿を作成しようとしています。

元となる文章はブログなどに書かれている長い文章ですが、メルマガで読みやすくするために1行全角30文字(半角60文字)ぐらいで自動的に改行を入れたいです。
mb_strlenやmb_substrで文字数を数えて、どこからどこまでを区切るというロジックを書こうとしましたが、文章の中に半角文字も含まれるため、文字数という概念で改行を入れると1行の文字数がそろっているように見えません。
一方バイト数で数えて文字を切っても、全角文字1文字が半分に区切られてしまっては読めなくなってしまいます。
それを解決するための関数やライブラリ、またはサンプルソースがあれば教えてください。

回答の条件
  • URL必須
  • 1人2回まで
  • 登録:
  • 終了:2009/03/04 06:28:43
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:GoldenDawn No.2

回答回数426ベストアンサー獲得回数81

ポイント35pt
<?php
function my_format($str, $width) {
  $ce = mb_internal_encoding() ;
  mb_internal_encoding(mb_detect_encoding($str)) ;

  if ($width <= 0) return $str ;
  for ($ret = '', $i = 0; $seg = mb_strimwidth($str, $i, $width); $i += mb_strlen($seg) + ($seg == ''))
    $ret .= ($seg = preg_replace('/(\r?\n).*/', '$1', $seg)).(preg_match('/[\r\n]$/', $seg) ? '' : "\n") ;

  mb_internal_encoding($ce) ;
  return $ret ;
}

$str = 'PHPでメルマガ用の原稿を作成しようとしています。
元となる文章はブログなどに書かれている長い文章ですが、メルマガで読みやすくするために1行全角30文字(半角60文字)ぐらいで自動的に改行を入れたいです。
mb_strlenやmb_substrで文字数を数えて、どこからどこまでを区切るというロジックを書こうとしましたが、文章の中に半角文字も含まれるため、文字数という概念で改行を入れると1行の文字数がそろっているように見えません。
一方バイト数で数えて文字を切っても、全角文字1文字が半分に区切られてしまっては読めなくなってしまいます。
それを解決するための関数やライブラリ、またはサンプルソースがあれば教えてください。' ;

echo '<pre>'
     .my_format($str, 60)
     .'</pre>' ;
?>

出力例

PHPでメルマガ用の原稿を作成しようとしています。
元となる文章はブログなどに書かれている長い文章ですが、メルマ
ガで読みやすくするために1行全角30文字(半角60文字)ぐらいで
自動的に改行を入れたいです。
mb_strlenやmb_substrで文字数を数えて、どこからどこまでを区切
るというロジックを書こうとしましたが、文章の中に半角文字も含
まれるため、文字数という概念で改行を入れると1行の文字数がそ
ろっているように見えません。
一方バイト数で数えて文字を切っても、全角文字1文字が半分に区
切られてしまっては読めなくなってしまいます。
それを解決するための関数やライブラリ、またはサンプルソースが
あれば教えてください。

mb_strimwidthという関数が便利。

id:wackey

mb_strimwidthという関数、初めて知りました。便利ですね!

ありがとうございます。

2009/03/02 14:34:34

その他の回答1件)

id:pahoo No.1

回答回数5960ベストアンサー獲得回数633

ポイント35pt

以下に折り返し関数の例を示します。1行分(改行コードを含まず)を折り返し処理するものです。内部処理は EUC-JP を用いています。

/**
 * 文字列を整形して返す(1行分)
 * @param   String $str  折り返したい文字列(SJIS,EUC-JP,UTF-8)
 * @param   int $width   折り返す桁数(半角1文字を1桁とする、0なら折り返さない)
 * @return  String 整形後の文字列(EUC-JP、最後に改行文字を付加)
*/
function my_format($str, $width) {
    mb_internal_encoding('EUC-JP');
    $str = mb_convert_encoding($str, 'EUC-JP', 'SJIS,EUC-JP,UTF-8');

    //折り返さない
    if ($width <= 0) {
        $dest = $str . "\n";
    //折り返す
    } else {
        $dest = '';
        $w = 0;
        $l = mb_strlen($str);
        for ($i = 0; $i < $l; $i++) {
            $ch = mb_substr($str, $i, 1, 'EUC-JP');
            $dest = $dest . $ch;
            if ($ch == "\n")    $w = 0;
            else                $w += mb_strwidth($ch);
            if ($w > $width) {
                $w = 0;
                $dest = $dest . "\n";
            }
        }
        $dest = $dest . "\n";
    }
    return $dest;
}
id:wackey

ありがとうございます!早速ソースまで見せていただき助かります!

後で実装して試してみます。

2009/03/02 10:46:06
id:GoldenDawn No.2

回答回数426ベストアンサー獲得回数81ここでベストアンサー

ポイント35pt
<?php
function my_format($str, $width) {
  $ce = mb_internal_encoding() ;
  mb_internal_encoding(mb_detect_encoding($str)) ;

  if ($width <= 0) return $str ;
  for ($ret = '', $i = 0; $seg = mb_strimwidth($str, $i, $width); $i += mb_strlen($seg) + ($seg == ''))
    $ret .= ($seg = preg_replace('/(\r?\n).*/', '$1', $seg)).(preg_match('/[\r\n]$/', $seg) ? '' : "\n") ;

  mb_internal_encoding($ce) ;
  return $ret ;
}

$str = 'PHPでメルマガ用の原稿を作成しようとしています。
元となる文章はブログなどに書かれている長い文章ですが、メルマガで読みやすくするために1行全角30文字(半角60文字)ぐらいで自動的に改行を入れたいです。
mb_strlenやmb_substrで文字数を数えて、どこからどこまでを区切るというロジックを書こうとしましたが、文章の中に半角文字も含まれるため、文字数という概念で改行を入れると1行の文字数がそろっているように見えません。
一方バイト数で数えて文字を切っても、全角文字1文字が半分に区切られてしまっては読めなくなってしまいます。
それを解決するための関数やライブラリ、またはサンプルソースがあれば教えてください。' ;

echo '<pre>'
     .my_format($str, 60)
     .'</pre>' ;
?>

出力例

PHPでメルマガ用の原稿を作成しようとしています。
元となる文章はブログなどに書かれている長い文章ですが、メルマ
ガで読みやすくするために1行全角30文字(半角60文字)ぐらいで
自動的に改行を入れたいです。
mb_strlenやmb_substrで文字数を数えて、どこからどこまでを区切
るというロジックを書こうとしましたが、文章の中に半角文字も含
まれるため、文字数という概念で改行を入れると1行の文字数がそ
ろっているように見えません。
一方バイト数で数えて文字を切っても、全角文字1文字が半分に区
切られてしまっては読めなくなってしまいます。
それを解決するための関数やライブラリ、またはサンプルソースが
あれば教えてください。

mb_strimwidthという関数が便利。

id:wackey

mb_strimwidthという関数、初めて知りました。便利ですね!

ありがとうございます。

2009/03/02 14:34:34

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません