【PHP】こんな関数あったんだ!wordwrapでラクして文字列を分割する

こんにちは。昔雑誌の編集をしていたことがあるので、どうしようもないとは思いつつも、文字列の禁則処理が何かと気になってしまうmuramatsuです。

今回はwordwrapについての解説です。

皆さんwordwrap関数ってあるのをご存知でしょうか?

あまり知られていないけど、知っていると意外と便利で、ラクしてまとまった文字列にすることができる関数。

とてもシンプルで、ちょっと使い方を覚えてしまえば初心者の方でも簡単に使えるようになります。

そんなwordwrapについての使い方を詳しく・わかりやすく解説していきます。

目次

wordwrapとは

shutterstock_683740147

wordwrap(ワードラップ)とは、文字列を指定した文字数に分けてくれる関数です。

指定した文字数に改行を入れたり、カンマ(,)を入れたりして、見やすい文字列にすることができます。

基本的なコード

$変数名 = wordwrap(文字列, 分割する文字数, 分割する部分に入れる文字[, true/ false]);
//第一引数=文字列、第二引数=分割する文字数、第三引数=分割部分に入れる文字、第四引数=true/false

$変数名は何でも構いません。わかりやすい名前をつけましょう。

第一引数文字列には分割したい文字列を入力します。文字列を代入した$変数を入れることも可能です。

第二引数分割する文字数は何文字ごとに文字列を分割したいか、数字を入れます。

第三引数分割する部分に入れる文字では、改行をしたい場合は「’<br/>’」または「”\n”」を入力します。他の文字を入れることも、もちろん可能です。

第四引数true / false
trueにした場合、文字列は常に分割する文字数に分けられます。
falseにした場合、分割する文字数がちょうど1単語の途中でも、単語の途中では分割されません。
単語の途中で区切り文字が入ってしまう場合は、その単語の前で区切られます。

wordwrapを使う~数字・英文編

shutterstock_97823570

wordwrapは、ある文字列に定期的な間隔で指定の文字やスペース、改行などを入れたい時に有効です。

ただ注意が必要なのは、wordwrapは基本的に英数字しか対応していません。日本語のようなマルチバイト文字では文字化けしてしまったり、1文字をバイト数で数えるので、思うように表示されません。

では早速具体的な実践方法を見ていきましょう。

文字の長さを指定して改行

<?php
$longword = 'Do you know the word of Pneumonoultramicroscopicsilicovolcanoconiosis? This is name of lung disease.';

//↓上記の文字列を30文字毎に改行をいれます
$words = wordwrap($longword, 30, '<br/>');

//出力をします。
echo $words;
?>

出力結果

Do you know the word of
Pneumonoultramicroscopicsilicovolcanoconiosis?
This is name of lung disease.

このサンプルでは$longwordに文字列を入れて、$wordsに30文字毎に改行を入れた文字列を代入します。
そしてechoで$wordsを出力させました。

出力結果を見ると、30文字毎に改行されているのがわかりますよね?

ここでは第四引数にtrueまたはfalseを入れていませんが、1単語の「Pneumonoultramicroscopicsilicovolcanoconiosis」が途中で切れていないことから、第四引数を指定しない場合デフォルト(初期設定)はfalseになっているのが分かります。

文字の長さとtrueを指定する

<?php
$longword = 'Do you know the word of Pneumonoultramicroscopicsilicovolcanoconiosis? This is name of lung disease.';

//↓上記の文字列を30文字毎に改行をいれ、さらにtrueを設定します。
$words = wordwrap($longword, 30, '<br/>', true);

echo $words;
?>

出力結果

Do you know the word of
Pneumonoultramicroscopicsilico
volcanoconiosis? This is name
of lung disease.

第四引数にtrueを入れたことにより、1単語45文字ある「Pneumonoultramicroscopicsilicovolcanoconiosis」が途中で切れて改行されていることが分かりますね。

また、はじめの行(Do you know the word of)を見ると、全部で30文字に達していなくても改行されています。

これは文字数だけではなく、1単語ずつで区切られていることが分かります。

つまり、むやみに1単語の途中で区切って改行することはないのです。

文字の長さとfalse

<?php
$longword = 'Do you know the word of Pneumonoultramicroscopicsilicovolcanoconiosis? This is name of lung disease.';

//↓上記の文字列を20文字毎に改行をいれ、さらにfalseを設定します。
$words = wordwrap($longword, 20, '<br/>', false);

echo $words;
?>

出力結果

Do you know the word
of
Pneumonoultramicroscopicsilicovolcanoconiosis?
This is name of lung
disease.

ここでは分割する文字数を20文字で設定しています。

この出力結果で分かることは、20文字で改行が入っていますが、2行目の「of」を見ると明らかに20文字でなくても改行が入っています。

これは「Pneumonoultramicroscopicsilicovolcanoconiosis」が指定した20文字を超える文字数の単語であり、かつ単語の途中で区切らないようfalseにしているため、「of」で改行が入ってしまうのです。

数字を区切る

<?php

//$numberには1億、$number2には10兆の数字を代入しています。
$number = 100000000;
$number2 = 1000000000000;

//3文字毎にカンマ(,)を入れます。
$yen = wordwrap($number, 3, ',', true);
echo $yen. '円<br/>';

$yen2 = wordwrap($number2, 3, ',', true);
//echoで3文字ごとにカンマを入れた数字の後に「円」を加えて出力します。
echo $yen2. '円<br/>';
?>

出力結果

100,000,000円
100,000,000,000,0円

ここでは1億と10兆の数字にそれぞれカンマ(,)を入れてみました。

wordwrap関数の第四引数はtrueにします。
これをfalseにすると「100000000」を1単語だととらえてしまうので、分割されません。

また10兆の数字の区切り方を見るとわかるように、頭(1)から3文字ずつ区切られていますね。

これは数字や文字の後ろからではなく、頭からカウントして区切っていることが分かります。

wordwrapを使う~マルチバイト文字編

shutterstock_310627304

wordwrapでは日本語のようなマルチバイト文字は対応していないと説明をしました。
実際出力はされますが、文字化けしてしまったり、1文字としてカウントしてくれません。

しかし日本語を使う私たちでは、それでは不便ですよね。

そこで、たくさんのPHPを使っている先輩方がマルチバイト文字でも使える関数を作ってくれています。

PHP公式サイト(wordwrap):http://php.net/manual/ja/function.wordwrap.php

上記サイトに記載されている関数1つを引用して日本語(全角文字)を出力してみましょう。(引用した関数に少しだけ手を加えています。)

<?php
function mb_wordwrap($string, $width=75, $break="\n", $cut = false) {
    if (!$cut) {
        $regexp = '#^(?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){'.$width.',}\b#U';
    } else {
        $regexp = '#^(?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){'.$width.'}#';
    }
    $string_length = mb_strlen($string,'UTF-8');
    $cut_length = ceil($string_length / $width);
    $i = 1;
    $return = '';
    while ($i < $cut_length) {
        preg_match($regexp, $string, $matches);
        $new_string = (!$matches ? $string : $matches[0]);
        $return .= $new_string.$break;
        $string = substr($string, strlen($new_string));
        $i++;
    }
    return $return.$string;
}


$storyline = '1単語45文字ある英単語を知っていますか?それはPneumonoultramicroscopicsilicovolcanoconiosisという単語で、日本語訳は超微視的珪質火山塵肺疾患という肺の病気の名前です。';
$story = mb_wordwrap($storyline, 21, '<br/>', true);

echo $story;
echo '<br/>';
echo '<br/>';

$storyline_mix = '1単語45文字ある英単語を知っていますか?それはPneumonoultramicroscopicsilicovolcanoconiosisという単語で、日本語訳は超微視的珪質火山塵肺疾患という肺の病気の名前です。';
$story2 = mb_wordwrap($storyline_mix, 21, '<br/>', true);

echo $story2;

echo '<br/>';
echo '<br/>';
?>

※上記引用したコード14行目を$new_string = (!$matches ? $string : $matches[0]);に変更しています。
また23行目以降も実際のコードとは異なります。

出力結果

1単語45文字ある英単語を知っていますか?
それはPneumonoultramicro
scopicsilicovolcanoco
niosisという単語で、日本語訳は超微視
的珪質火山塵肺疾患という肺の病気の名前です
。

1単語45文字ある英単語を知っていますか?
それはPneumonoultramicro
scopicsilicovolcanoco
niosisという単語で、日本語訳は超微視
的珪質火山塵肺疾患という肺の病気の名前です
。

$storylineには全角文字列を代入し、$storyline_mixには全角日本語と半角英数字が混ざった文字列を代入して21文字ごとに改行を入れ、それぞれ出力させてみました。

$storyline_mixの出力結果を見ていただくと分かりますが、半角でも1文字1カウントされています。

もし$storyline_mixを全角文字の対応をしていないwordwrap関数で出力したらどうなるでしょうか?

<?php
$storyline_mix = '1単語45文字ある英単語を知っていますか?それはPneumonoultramicroscopicsilicovolcanoconiosisという単語で、日本語訳は超微視的珪質火山塵肺疾患という肺の病気の名前です。';

$line = wordwrap($storyline_mix, 21, '<br/>', true);

echo $line. '<br/>';
?>

出力結果

1単語45文字ある
英単語を知って
いますか?それ
はPneumonoultramicro
scopicsilicovolcanoco
niosisという単語
で、日本語訳は
超微視的珪質火
山塵肺疾患とい
う肺の病気の名
前です。

wordwrap関数では、全角1文字を1カウントしているわけではなく、バイト数(文字の単位数)でカウントします。
ここではスクリプト(テキストエディタ)の文字コード設定を「UTF-8」にしているため全角1文字を3バイト、半角1文字を1バイトとカウントして出力しています。

つまり1行目は半角数字が3つで3バイト、全角文字が6文字で計18バイトの合計21バイトで改行が入っているのが分かりますね。

このバイト数はエンコーディング(文字の種類)によって全角1文字を3バイトとカウントしたり、2バイトとカウントしたりと様々なので注意しましょう。

まとめ

いかがでしたか?

wordwrap関数では、文字列に指定した文字数分ごとに改行や入れたい文字を入れてくれるということが分かりました。

使い方はシンプルでとっても簡単なので、初心者の方でも気軽に使うことができます。

基本的には半角英数字が対象ですが、全角でも対応する関数が出てきているので、うまく使いこなし、ラクしてまとまった文字列を出力できるようにしてみましょう。

この記事を書いた人

世界中の人たちと友達になって、その友達の家を巡る旅をしたいと密かに思っている。

複雑な内容を誰にでもわかりやすく、そして納得のいくような解説をする、をモットーにしています!

目次