カテゴリ: Ruby 更新日: 2025/12/25

RubyのString#lengthとbytesizeの違いを徹底解説!文字数カウントの落とし穴とUTF-8対応

String#lengthとbytesizeの違いは?文字数カウントの落とし穴【UTF-8対応】
String#lengthとbytesizeの違いは?文字数カウントの落とし穴【UTF-8対応】

先生と生徒の会話形式で理解しよう

生徒

「先生、Rubyで文字列の長さを数えるときにlengthbytesizeってありますけど、どっちを使えばいいんですか?」

先生

「とても良い質問ですね。String#lengthString#bytesizeは似ていますが、実は“数えているもの”が全く違うんです。」

生徒

「えっ、違うんですか?どっちも文字の長さを数えているんじゃないんですか?」

先生

「実はlengthは“文字数”を、bytesizeは“バイト数”を数えるんです。日本語のようなマルチバイト文字を扱うときに大きな違いが出てくるので、しっかり覚えておきましょう!」

1. Rubyの文字列とエンコーディングの関係

1. Rubyの文字列とエンコーディングの関係
1. Rubyの文字列とエンコーディングの関係

Rubyの文字列(String)は、単なる文字の集まりではなく、「どのような文字コードで表現されているか(エンコーディング)」という情報も持っています。エンコーディングとは、「文字をデジタルデータ(バイト列)としてどう保存するか」というルールのことです。

たとえば、日本語の「こんにちは」はUTF-8という文字コードでは1文字あたり3バイトで表現されます。つまり、見た目は5文字でも、実際には15バイトのデータになるのです。

このように「文字数」と「バイト数」は異なる概念なので、lengthbytesizeでは結果が変わることがあります。

2. String#lengthとは?(文字数を数えるメソッド)

2. String#lengthとは?(文字数を数えるメソッド)
2. String#lengthとは?(文字数を数えるメソッド)

String#lengthは「文字列の中に何文字あるか」を数えます。日本語のようにマルチバイト文字でも、見た目の通り1文字としてカウントされます。


text = "こんにちは"
puts text.length

5

このように、「こんにちは」は5文字なのでlengthの結果は「5」です。英数字やひらがな、漢字など、文字の種類に関係なく“目に見える文字の数”を数えます。

3. String#bytesizeとは?(バイト数を数えるメソッド)

3. String#bytesizeとは?(バイト数を数えるメソッド)
3. String#bytesizeとは?(バイト数を数えるメソッド)

String#bytesizeは「その文字列をバイト列にしたときの長さ」を返します。つまり、文字ではなく「データの容量」を数えているのです。


text = "こんにちは"
puts text.bytesize

15

UTF-8では日本語の1文字は3バイトなので、「こんにちは」は5文字×3バイト=15バイトとなります。これがbytesizeの結果です。

たとえば、ファイルサイズの計算やネットワーク通信で送るデータの容量を知りたいときにはbytesizeを使うのが正解です。

4. lengthとbytesizeの違いを比較しよう

4. lengthとbytesizeの違いを比較しよう
4. lengthとbytesizeの違いを比較しよう

ここで英語の文字列と日本語の文字列を比べてみましょう。英語(ASCII文字)は1文字=1バイトですが、日本語(UTF-8)は1文字=3バイトになることが多いです。


english = "Hello"
japanese = "こんにちは"

puts english.length    # => 5
puts english.bytesize  # => 5

puts japanese.length   # => 5
puts japanese.bytesize # => 15

5
5
5
15

この結果から、同じ「5文字」でも、英語は5バイト、日本語は15バイトになります。つまり、「見た目の文字数」と「内部のデータサイズ」は必ずしも一致しません。

5. UTF-8とShift_JISで結果が違う!

5. UTF-8とShift_JISで結果が違う!
5. UTF-8とShift_JISで結果が違う!

Rubyは文字列ごとにエンコーディングを持っているため、同じ文字でもエンコーディングによってbytesizeの結果が変わります。Shift_JISでは1文字=2バイトなので、UTF-8と比較すると結果が異なります。


text = "あいう"
puts text.bytesize                   # UTF-8: 9バイト
puts text.encode("Shift_JIS").bytesize # Shift_JIS: 6バイト

9
6

このように、文字コードを変えるとデータサイズも変わります。特にファイル入出力や外部APIとの通信では、文字化けの原因にもなるので注意が必要です。

6. 文字数カウントの落とし穴と注意点

6. 文字数カウントの落とし穴と注意点
6. 文字数カウントの落とし穴と注意点

初心者がよくやってしまうのが、「文字数を調べたいのにbytesizeを使ってしまう」パターンです。すると、日本語を含む文字列で予想外の値が返ってきます。

たとえば、「Twitterの投稿文字数」や「入力フォームのバリデーション(文字数制限)」を作るときに、bytesizeで判定してしまうと誤差が出ることがあります。

反対に、「データの転送量」や「ファイルの保存サイズ」を知りたいときにlengthを使っても正しい結果にはなりません。

つまり、用途に応じて正しいメソッドを選ぶことが大切です。

7. 実践:文字数とバイト数を両方チェックするサンプル

7. 実践:文字数とバイト数を両方チェックするサンプル
7. 実践:文字数とバイト数を両方チェックするサンプル

最後に、文字数とバイト数を同時にチェックするプログラムを作ってみましょう。UTF-8環境での違いがよく分かります。


def check_string_info(str)
  puts "文字列: #{str}"
  puts "文字数(length): #{str.length}"
  puts "バイト数(bytesize): #{str.bytesize}"
  puts "エンコーディング: #{str.encoding}"
end

check_string_info("Hello")
check_string_info("こんにちは")

文字列: Hello
文字数(length): 5
バイト数(bytesize): 5
エンコーディング: UTF-8

文字列: こんにちは
文字数(length): 5
バイト数(bytesize): 15
エンコーディング: UTF-8

このように、同じUTF-8でも日本語と英語でバイト数が異なります。Rubyの文字列操作を正しく理解するためには、「文字数」と「バイト数」の違いを意識することが大切です。

8. lengthとbytesizeを使い分けよう

8. lengthとbytesizeを使い分けよう
8. lengthとbytesizeを使い分けよう

ここまで見てきたように、RubyのString#lengthは「文字数」、String#bytesizeは「データ容量(バイト数)」を表します。

  • 文字数を数えたいときlength
  • データサイズを知りたいときbytesize

特に日本語や絵文字などマルチバイト文字を扱うときには、UTF-8での1文字=複数バイトという点を忘れずに、目的に応じたメソッドを選びましょう。

まとめ

まとめ
まとめ

Rubyのlengthとbytesizeを正しく理解する重要性

この記事では、Rubyにおける String#lengthString#bytesize の違いについて、UTF-8を中心とした文字コードの仕組みとあわせて詳しく解説してきました。Rubyで文字列を扱う際、「文字数」と「バイト数」を同じものとして考えてしまうと、思わぬ不具合や仕様ミスにつながることがあります。特に日本語を含むアプリケーション開発では、この違いを正しく理解しているかどうかが、プログラムの品質に大きく影響します。

length は、人が目で見て認識する「文字の数」を数えるためのメソッドです。ひらがな、カタカナ、漢字、英数字など、文字の種類に関係なく、表示される文字の個数をそのまま返します。そのため、入力フォームの文字数制限や、文章の長さチェック、投稿文字数の判定など、「ユーザーが意識する文字数」を扱う場面では length を使うのが自然です。

一方で bytesize は、文字列が内部的にどれくらいのデータ量を持っているか、つまり「バイト数」を返します。UTF-8では、日本語や多くの記号が1文字あたり複数バイトで表現されるため、見た目の文字数と実際のバイト数が一致しません。この特性は、ファイル保存時のサイズ計算や、ネットワーク通信、外部API連携など、データ量そのものが重要になる処理で特に重要です。

また、Rubyの文字列はエンコーディング情報を保持しており、UTF-8やShift_JISなど、文字コードが変わると bytesize の結果も変化します。同じ日本語の文字列でも、使用するエンコーディングによってバイト数が異なるため、環境依存の不具合を防ぐためにも、エンコーディングを意識した設計が欠かせません。

初心者がつまずきやすいポイントとして、「文字数を制限したいのに bytesize を使ってしまう」「ファイルサイズを知りたいのに length を使ってしまう」といったケースがあります。これらは一見小さな違いに見えますが、実際の開発現場では致命的なバグにつながることもあります。だからこそ、Rubyで文字列操作を行う際は、「今、自分は何を数えたいのか」を常に意識することが大切です。

まとめとしての確認用サンプルプログラム


def summary_check(str)
  puts "対象の文字列: #{str}"
  puts "文字数(length): #{str.length}"
  puts "バイト数(bytesize): #{str.bytesize}"
  puts "使用中のエンコーディング: #{str.encoding}"
  puts "----------------------------"
end

summary_check("Ruby")
summary_check("日本語テキスト")

このサンプルでは、同じ仕組みで英語と日本語の文字列をチェックしています。出力結果を見ることで、文字数は同じ考え方で数えられている一方、バイト数は文字の種類やエンコーディングによって大きく変わることが直感的に理解できます。実際の開発でも、このように確認しながら進めることで、ミスを未然に防ぐことができます。

先生と生徒の振り返り会話

生徒

「length と bytesize が全然違う役割だということが、やっと腑に落ちました。今までは何となく使っていました。」

先生

「それに気付けたのは大きな成長ですね。Rubyでは文字列の扱いがとても柔軟なので、仕組みを理解すると応用が利くようになります。」

生徒

「文字数制限のときは length、データ量やサイズを見るときは bytesize、と使い分ければいいんですね。」

先生

「その通りです。さらにエンコーディングも意識できるようになると、文字化けや不具合にも強くなりますよ。」

生徒

「Rubyで日本語を扱うときに注意すべき理由が、よく分かりました。」

先生

「理解できていれば大丈夫です。ぜひ実際のプログラムでも、length と bytesize を意識して使ってみてください。」

関連記事:
カテゴリの一覧へ
新着記事
New1
Ruby
“すべてはオブジェクト”を体感!初心者向けRubyのオブジェクト指向入門【irbで学ぶ】
New2
Ruby
Rubyの標準入出力を完全ガイド!puts・print・pの違いとデバッグ活用法
New3
Ruby
Gemとは?RubyGemsとBundlerを初心者向けに完全解説!依存関係管理も図解でわかりやすく理解
New4
Ruby
Rubyの文字エンコーディング入門!UTF-8・マジックコメント・外部/内部エンコーディングを完全解説
人気記事
No.1
Java&Spring記事人気No1
Ruby
Rubyのreduceとinject入門!合計計算や集計を初心者向けに分かりやすく解説
No.2
Java&Spring記事人気No2
Ruby
Rubyの文字列エンコーディング完全ガイド!Encoding・force_encoding・encodeを初心者向け解説
No.3
Java&Spring記事人気No3
Ruby
Rubyの始め方ガイド:インストールから最初のHello Worldまで(Windows/Mac/Linux)
No.4
Java&Spring記事人気No4
データベース
PostgreSQLのWHERE句を徹底解説!初心者でもわかるSQLデータ抽出の基本
No.5
Java&Spring記事人気No5
Ruby
Rubyのfind/detect/find_indexを徹底解説!目的のデータを素早く探す方法
No.6
Java&Spring記事人気No6
Ruby
Rubyで比較演算子を完全解説!==・===・<=>・eql? の使い分け
No.7
Java&Spring記事人気No7
Ruby
Rubyのselect/reject/filterの使い方を完全解説!初心者向けの条件抽出レシピ
No.8
Java&Spring記事人気No8
データベース
PostgreSQLで順位付け!ROW_NUMBER関数の使い方を初心者向けに徹底解説