[PHP] 半角や全角のテキストに対するsubstrとmb_substrの動作の違い

2018年8月4日(更新: 2018年8月6日)

PHPで、ある文字列(テキスト)から特定の位置を切り出す場合には、関数 substr または mb_substr を使うことができます。

ドキュメントによれば mb_substr はマルチバイト文字全角文字)に対応した substr であると説明されています。

mb_substr
文字数に基づきマルチバイト対応の substr() 処理を行います。位置は、strの始めから数えられます。最初の文字の位置は0、2番目の文字の位置は1、といったようになります。
PHP: mb_substr – Manual

マルチバイト文字を含むテキストに対して substr を実行した結果と、逆に半角英数字のみのテキストに対して mb_substr を実行した結果について気になったので、実際に実行して結果を調べてみました。

サンプルスクリプト

三種類のテキスト(半角英数字のみのテキスト、全角文字のみのテキスト、全角半角が混在したテキスト)に対して、それぞれ substr および mb_substr を実行するPHPスクリプトです。

<?php
mb_internal_encoding("utf-8");

$singleByteText = 'abcdefg1234567'; // 半角英数のみ
$multiByteText = 'あいうえおかき1234567'; // 全角のみ
$mixText = 'あいうえおabcd123451234'; // 混在

echo substr($singleByteText, 4, 8), '<br>';
echo mb_substr($singleByteText, 4, 8), '<br>';

echo substr($multiByteText, 4, 8), '<br>';
echo mb_substr($multiByteText, 4, 8), '<br>';

echo substr($mixText, 4, 8), '<br>';
echo mb_substr($mixText, 4, 8), '<br>';
?>

各文字列の5文字目から8つ文字を切り出して表示しています。

実際の出力結果は以下のようになりました。

全角半角テキストにsubstrおよびmb_substrを使用した結果

以上の結果から、次のことがわかりました。

  • マルチバイト文字を含むテキストに対する substr は正常な結果が得られない
  • 半角英数字のみのテキストに対する mb_substr は substr と同じ動作となる
  • mb_substr は半角、全角およびそれらが混在しているテキストに使用できる

よって、あるテキストがマルチバイト文字を含む可能性がある場合は mb_substr を使うべきであると言えます。

全角半角に関わらず、指定した文字数のテキストを抽出したい場合は mb_substr を使って以下のように記述します。

// 切り出す対象のテキスト
$targetText = 'あaいiうuえeおo';

// 切り出したい文字数
$length = 5;

echo mb_substr($targetText, 0, $length); // あaいiう

以上 substr と mb_substr の動作の違いについてでした。

マルチバイト文字を対象とする関数

PHPには、他にもマルチバイト文字を対象とする関数が複数存在します。これらは接頭辞としてmbmulti byte の略)が付けられています。

例えば mb_strlenmb_strposmb_substr_count といった関数があります。これらの関数を使う基準も、対象とする文字列に全角文字が含まれる可能性があるかどうかであると言えます

マルチバイト文字を扱う関数の詳しい説明や種類はドキュメントの以下のページをご覧ください。

PHP: マルチバイト文字列 – Manual

コメントを残す

メールアドレスが公開されることはありません。