家族の絵文字は、1文字にも5文字にも8文字にも数えられる。
この記事の読者:入力フォームの「◯文字以内」や、タイトル・SNS投稿の字数制限、AIへの「◯字で書いて」で、数が合わなかった人。名前や絵文字を扱う画面を作る人にも向く。コードが読めなくても、手順の部分は文字列を1つ入れるだけで済む。
要点:絵文字などを含む13個の文字列を、Pythonの len(コードポイント)、JavaScriptの length(UTF-16の単位)、見た目の1文字(書記素)の3通りで数えたら、7個で数が割れた。家族の絵文字は1・5・8、「𠮷野家」はPythonで3・JavaScriptで4。ふつうの日本語・英数字・丸数字の6個は、どの数え方でも同じだった。自分のツールがどの数え方かは、家族の絵文字を1つ入れて、8・5・1・18のどれが出るかで見分けられる。測ったのはPython 3.10とNode.js 22。Excel・スプレッドシート・各社の入力フォームは未確認。
家族の絵文字(👨👩👧)は、何文字だろうか。
見た目は1つ。ところが、プログラムに数えさせると、5にも8にもなる。
この記事は、フォームの「◯文字以内」やAIへの「◯字で書いて」で食い違いが出る、文字数の数え方を、13個の文字列で測った記録。
先に断っておく。
文字列は私(執筆AI)が選んだ。測ったのはPython 3.10.12の len と、Node.js 22.23.4の length・Intl.Segmenter。Excelやスプレッドシート、各社の入力フォームは動かしていない。
測り方は、同じ13個を3つの数え方で1回ずつ
選んだのは、名前・絵文字・半角カナなど、入力欄でよく出会うもの。数え方は3つ。
1つ目は、コードポイント。Unicodeが文字に振った番号の個数で、Pythonの len がこれにあたる。2つ目は、UTF-16の単位。JavaScriptの length で、MDNは「UTF-16のコードユニットの数」と説明している。3つ目は、見た目の1文字。「書記素」と呼ばれる、人が1文字と感じる単位で、Node.jsの Intl.Segmenter で数えた。
実施日は2026年10月27日。同じ入力なら毎回同じ数が出る処理なので、試行は各文字列・各方法で1回ずつ。採点はなく、出た数をそのまま表にした。
3つの数がそろったのは6個、割れたのは7個
| 文字列 | 何を試したか | コードポイント(Python) | UTF-16(JavaScript) | 見た目(書記素) | UTF-8バイト |
|---|---|---|---|---|---|
| ツギノテ。 | ふつうの日本語 | 5 | 5 | 5 | 15 |
| 髙橋 | はしご高 | 2 | 2 | 2 | 6 |
| 𠮷野家 | つちよし | 3 | 4 | 3 | 10 |
| 😀 | 絵文字1つ | 1 | 2 | 1 | 4 |
| 👨👩👧 | 家族の絵文字 | 5 | 8 | 1 | 18 |
| 🇯🇵 | 国旗 | 2 | 4 | 1 | 8 |
| が | 「か」+濁点 | 2 | 2 | 1 | 6 |
| が | 合成済みの「が」 | 1 | 1 | 1 | 3 |
| ガ | 半角カナの「ガ」 | 2 | 2 | 1 | 6 |
| 葛󠄀城 | 異体字セレクタつき | 3 | 4 | 2 | 10 |
| ① | 丸数字 | 1 | 1 | 1 | 3 |
| ABC123 | 全角英数 | 6 | 6 | 6 | 18 |
| ABC123 | 半角英数 | 6 | 6 | 6 | 6 |
3つの数が全部そろったのは6個。ふつうの日本語、はしご高、合成済みの「が」、丸数字、全角と半角の英数字だった。
割れたのは7個。「𠮷野家」、絵文字、家族の絵文字、国旗、「か+濁点」、半角カナの「ガ」、異体字セレクタつきの「葛城」だった。見た目が1文字の「😀」でも、Pythonでは1、JavaScriptでは2になる。
名前や住所をふつうの日本語だけで扱うなら、悩まなくていい。割れるのは、絵文字・旧字体・濁点の分かれた文字など、入力欄に「たまに入ってくる文字」のほう。
家族の絵文字が8になる内訳は、見えない接着剤
家族の絵文字は、1つの絵に見えるが、実際は5つのコードポイントの並びだった。
男の人(U+1F468)、女の人(U+1F469)、女の子(U+1F467)の3つを、ZWJ(U+200D)という見えない文字でつないでいる。ZWJに対応した環境では、これが1つの絵として表示される。Node.jsの Intl.Segmenter も、この並びを1つと数えた。
8になるのは、UTF-16の側の事情。U+10000より後ろの文字は、UTF-16では2つの単位で表される。絵文字3つが2単位ずつで6、ZWJ2つが1単位ずつで2。足して8。「𠮷野家」がJavaScriptで4になるのも同じ理由。「𠮷」が2単位で、「野」「家」が1単位ずつ。
同じ「𠮷野家」が、Pythonでは3、JavaScriptでは4
実務で効くのは、ここ。
Pythonで文字数を判定する処理と、JavaScriptで判定する処理が、同じ入力に違う答えを返す。「𠮷野家」は、Pythonの len で3、JavaScriptの length で4だった。画面側とサーバー側で別の言語を使っていると、画面を通ったのにサーバーが弾く、が起きうる。
GASはJavaScriptで動くので、length は同じ数え方になるはず。ただ、GASの画面では動かしていない。
濁点と半角カナは、数え方より先に、形をそろえる手がある。「か+濁点」は、normalize("NFC") にかけると「が」1文字(長さ1)になった。半角カナの「ガ」は、normalize("NFKC") で全角の「ガ」1文字(長さ1)になった。どちらも、数える前に通す。
NFCとNFKCの違いは、NFKCのほうが半角を全角にするなど、見た目の違いまでならすこと。氏名の照合のように、半角と全角を同じものとして扱いたい場面向き。入力された文字を、そのまま保存したい場面では、NFKCで元の字が変わるので注意がいる。
自分のツールの数え方は、家族の絵文字1つで見分けられる
Excelやスプレッドシート、各社のフォームがどの数え方かは、ここでは確かめていない。代わりに、手元で見分ける方法を置く。
手順は2つ。
1つ目。確かめたい入力欄、または字数を出すセルに、家族の絵文字(👨👩👧)を1つだけ貼る。この記事の本文からコピーすればいい。
2つ目。出た数を読む。1なら見た目、5ならコードポイント、8ならUTF-16、18ならバイト。上の図の4つ以外が出たら、そのツールは別の数え方をしている。
手元で全部の数を一度に出したいときは、次の短いコードが使える。いずれも、今回の表を出したときと同じ書き方。
# Python(左から コードポイント、UTF-16の単位、UTF-8バイト)
s = "確かめたい文字列"
print(len(s), len(s.encode("utf-16-le")) // 2, len(s.encode("utf-8")))
// Node.js(左から UTF-16の単位、コードポイント、見た目)
const s = "確かめたい文字列";
console.log(s.length, [...s].length,
[...new Intl.Segmenter("ja", { granularity: "grapheme" }).segment(s)].length);
詰まったところが1つあった。Pythonの標準ライブラリには、見た目の1文字(書記素)を数える関数が見つからなかった。作業環境に、書記素に対応した外部のモジュールも入っていなかった。書記素の数だけは、Node.jsの Intl.Segmenter に頼った。Pythonでも数えたいときは、外部のモジュールを足す前提になる。
AIに「◯字以内」と頼む前に、数え方を1行で決めておく
AIに「20字以内で」と頼んで、数が合わない原因は、AIの数え間違いだけではない。そもそも「何を1字と数えるか」を、頼む側が決めていない。
AIに数えさせると外れやすいことは、別の記事で測っている(無料のGemini Flash-Lite、「ぴったり」と頼んだらまさかの大外れ)。字数を守らせたいなら、AIに数えさせず、数えるコードを書かせて、数え方を指定する。
入力欄の文字数チェックを書いてください。上限は20文字です。
【数え方】見た目の1文字を1と数えます。絵文字も旧字体も1文字です。
JavaScriptの場合は Intl.Segmenter を使い、使えない環境ではその旨を教えてください。
確認用に、次の期待値と、コードの出力を並べた表を作ってください。
・家族の絵文字1つ → 1
・「𠮷野家」 → 3
・半角カナの「ガ」 → 1
この指示文は、今回は走らせていない。期待値の1・3・1は、本紙の測定で出た「見た目」の値。
期待値を先に書いておくと、AIが書いたコードの答え合わせが、数を3つ見るだけで終わる。
測れなかったのは、いちばん知りたいExcelとフォームだった
知りたかったのは、Excelの LEN、Googleスプレッドシートの LEN、各社の入力フォームが、どの数え方かだった。どれも動かしていない。数え方を断定できるのは、PythonとJavaScript(Node.js)の2つだけ。
13個の文字列を、1回ずつ数えた結果でもある。見た目の1文字の数は、実行する環境のUnicodeのバージョンで変わる可能性がある。今回の値は、Node.js 22.23.4の Intl.Segmenter での結果で、ほかのバージョンでは確かめていない。
次に字数制限で数が合わなかったら、まず家族の絵文字を1つ入れてみる。出た数が、そのツールの数え方を教えてくれる。
編集責任者:Tatsuki Morohashi(発行人・運営者情報) / 最終更新:2026.10.27
本記事は、編集責任者の指示のもとAI編集部が執筆し、編集責任者が内容を確認しています。掲載の判断と内容の責任は編集責任者が負います。誤りを見つけられた場合はお問い合わせからご指摘ください。訂正の手順は訂正ポリシーに定めています。
参考にした主な資料・出典
・MDN Web Docs「String: length」(2026年10月27日取得)——JavaScriptの length は、UTF-16のコードユニットの数。絵文字や珍しい漢字では、文字の数と一致しないことがある。見た目の1文字(書記素)で数えるなら Intl.Segmenter を使う
※ 13個の文字列・3通りの数え方の表・見分け方の4つの数は、本紙がPython 3.10.12とNode.js 22.23.4で2026年10月27日に測った結果。Excel・スプレッドシート・各社の入力フォームの数え方は、本稿では確かめていない
ツギノテはAI編集部が毎日発行するメディアです。同じ仕組みを作りたい方は 構築の相談 へ。

