最后更新:

全角与半角的区别 - 对字符计数的影响详解

9 分钟阅读

全角半角转换工具

粘贴文本,即可将英文字母、数字、片假名、标点符号和空格在全角与半角之间即时互转。转换完全在浏览器中完成,输入内容不会发送到服务器。

转换方向
转换对象

平假名、汉字和 emoji 不会被转换。波浪号 〜 (U+301C) 也保持原样,只有全角波浪线 ~ (U+FF5E) 会被转换。

转换工具的使用方法

只需三步:(1) 将文本粘贴到输入框,(2) 选择转换方向 (全角 → 半角,或反向),(3) 用复选框指定转换对象 (英文字母和数字、片假名、标点符号、空格)。结果随输入实时更新,无需点击转换按钮。点击"复制结果"即可将转换后的文本用于表单填写或 CSV 数据整理。将结果粘贴到字符计数器,还可以分别查看全角和半角字符的数量。

哪些字符会被转换,哪些不会

本工具不使用 NFKC 之类的一揽子标准化,而是仅依据明确的对照表,转换全角字符与半角字符之间存在一一对应关系的字符。

另一方面,平假名、汉字、emoji (包括 ZWJ 组合序列) 和组合字符在任何方向都不会被改动。下文"灰色地带字符"中介绍的波浪号 〜 (U+301C) 与全角波浪线 ~ (U+FF5E) 是不同的字符,因此被有意排除在转换范围之外。没有半角形式的片假名 (ヰ、ヱ、ヵ、ヶ 等) 也会保持原样。

什么是全角和半角

全角 (Full-width) 和半角 (Half-width) 的概念源于等宽字体时代。全角字符占据一个完整的字符宽度,半角字符占据一半的宽度。按 East Asian Width 属性,各类字符的归属如下。

类别全角示例半角示例说明
英文字母A B CA B C全角英文字母在日常使用中较少见
数字1 2 31 2 3全角数字在正式文档中偶尔使用
片假名ア イ ウア イ ウ半角片假名在旧系统中常见
标点符号。 、 !. , !中日文通常使用全角标点
空格 (U+3000) (U+0020)全角空格宽度是半角的两倍

中文汉字、日文平假名和片假名天然就是全角字符,没有对应的半角形式 (半角片假名除外)。而英文字母和数字既有全角形式也有半角形式。

半角片假名之所以被视为"不推荐使用",原因出自 JIS X 0201 规范。1969 年制定的这一规范为了把片假名装进 7 位 / 8 位有限的编码空间,把浊音符号 (゙) 与半浊音符号 (゚) 定义为独立字符。其结果是"ガ"会以"ガ"的形式被计为 2 个字符。即使施加 Unicode 的 NFC 标准化,半角片假名的浊音符号也不会被合成,容易造成字数统计不一致,因此除有特别理由外都应使用全角片假名。

Unicode 如何定义全角与半角 —— East Asian Width 属性

"全角"和"半角"这两种叫法源自日语圈,但在 Unicode 规范中有正式定义,即 UAX #11 (Unicode Standard Annex #11: East Asian Width)。每个码位都会被赋予以下 6 种宽度属性之一。

日常被称作"全角"的字符同时包含 F 和 W,"半角"则包含 H 和 Na。尤其需要留意 A (Ambiguous) 这一类,它会随终端和编辑器的设置既可能显示为 1 个字符宽,也可能显示为 2 个字符宽。例如"α" (希腊小写字母 alpha) 在 Windows 命令提示符中显示为全角宽度,而在 macOS 终端中有时显示为半角宽度。

JIS X 0201 与 JIS X 0208 —— 全角半角的历史由来

全角与半角之分,与日本字符编码规范的发展密切相关。1969 年制定的 JIS X 0201 在 ASCII 兼容的 7 位编码之外,把 63 个半角片假名收录进 8 位区域。那是 1 个字符 = 1 字节的世界。

1978 年制定的 JIS X 0208 定义了包含 6,349 个汉字的大规模字符集。1 字节只能表示 256 种取值,因此需要 2 字节的编码空间。正是这种"单字节字符"与"双字节字符"在物理尺寸上的差异,在等宽字体环境中被可视化为"半角"与"全角"的显示宽度之别。

换言之,"全角 = 2 字节"在 Shift_JIS 和 EUC-JP 这类编码中曾经是事实,但在 UTF-8 成为主流的今天已不再成立。尽管如此,这个等式依然根深蒂固,原因是日本 IT 行业在 1990~2000 年代建成的许多系统都以 Shift_JIS 为前提。

全角半角对字符计数的影响

不同平台和系统对全角半角的计数方式不同,这是造成字数统计混乱的主要原因。

平台/系统计数方式"A" 的计数"A" 的计数
Unicode 字符数每个码点 = 111
UTF-8 字节数按字节计算3 字节1 字节
Shift_JIS 字节数按字节计算2 字节1 字节
X (Twitter)加权字符11
某些日本系统全角=2,半角=121

特别需要注意的是,某些日本的传统系统 (银行、政府机构等) 仍然使用"全角 = 2 字节、半角 = 1 字节"的计数方式。在这些系统中,"ABC" (半角) 计为 3,而"ABC" (全角) 计为 6。

以"Hello 世界"为例,同一段文本在不同计数方式下的结果如下。

计数方式"Hello 世界"的结果
Unicode 字数 (通用)7 个字符
字节数 (Shift_JIS)9 字节 (5+4)
字节数 (UTF-8)11 字节 (5+6)
字节数 (UTF-16)14 字节 (全部字符 × 2)

把主要平台在全角半角计数上的差异也掌握清楚,在实务中很有帮助。

平台计数方式全角的处理
X (原 Twitter)自有的加权方式日文 1 个字符 = 2 个字符份 (280 字符中占 140 字符份)
LINEUnicode 字数全角与半角均为 1 个字符
SMS取决于编码日文每条最多 70 个字符 (UCS-2)
MySQL VARCHAR(n)字数 (utf8mb4)全角与半角均为 1 个字符 (但另有字节上限)
Oracle VARCHAR2(n BYTE)字节数UTF-8 下全角 1 个字符消耗 3 字节
Google Ads (标题・描述)自有的换算方式全角 1 个字符按 2 个字符计 (2026 年 8 月时点)

这张表真正想说明的是,同一个"1 个字符"在各种方式下指的并不是同一件事。按码位计数的方式与把全角折算成 2 个字符的方式同时存在,因此在贴着上限写的稿件里,明明本地数着刚好够,到了投稿前的最后一步却突然不够了。写作之前先确认目标平台采用哪一种方式,是最省事的做法。

本站的字符计数器会分别显示全角与半角各自的字数,因此两种方式都能应对。

UTF-8 编码下的字节数差异

在现代 Web 开发中最常用的 UTF-8 编码下,全角和半角字符的字节消耗差异显著。了解字符数与字节数的区别对于数据库设计和 API 开发至关重要。

字符类型UTF-8 字节数示例
半角英数字1 字节A, 1, @
全角英数字3 字节A, 1
中文汉字3 字节中,文
日文平假名3 字节あ, い
半角片假名3 字节ア, イ
全角标点3 字节。、!
半角标点1 字节. , !

各编码下的字节大小对比

即使是同一个字符,字节数也会因编码而大不相同。下表对比了代表性字符在各编码下的字节大小。

字符UTF-8UTF-16Shift_JISEUC-JP
A (半角英文字母)1 字节2 字节1 字节1 字节
あ (平假名)3 字节2 字节2 字节2 字节
漢 (汉字)3 字节2 字节2 字节2 字节
A (全角英文字母)3 字节2 字节2 字节2 字节
ア (半角片假名)3 字节2 字节1 字节2 字节
€ (欧元符号)3 字节2 字节无法转换无法转换
𠮷 (CJK 扩展 B)4 字节4 字节 (代理对)无法转换无法转换

值得注意的是,在 UTF-8 下半角片假名"ア"要消耗 3 字节。在 Shift_JIS 中只占 1 字节的半角片假名,到了 UTF-8 就和全角平假名一样是 3 字节。"半角所以数据量小"这种直觉,在 UTF-8 环境下并不总是正确。

用错全角半角会怎样 —— 失败案例集

全角与半角混用会引发以下这些问题。

常见问题与解决方法

全角半角的使用规范

在中文写作中,全角半角的使用有一些通用规范:

日文写作中的惯例与此略有不同,处理日文文本时可作如下参考。

  1. 英文字母和数字一般使用半角 (例:2024 年、100 日元)
  2. 日文句子中的括号使用全角 (例:"你好"对应的直角引号)
  3. URL 和电子邮件地址必须以半角输入
  4. 填写表单时遵从其指定的形式 (全角或半角)

编程中全角字符的陷阱

尤为严重的是编程中混入全角空格 (U+3000)。它在外观上很难与半角空格 (U+0020) 区分,即使看到错误信息也往往察觉不到原因。

语言错误信息
PythonSyntaxError: invalid character ' '
Javaillegal character: ' '
JavaScriptSyntaxError: Invalid or unexpected token
C/C++error: stray '\343' in program (UTF-8 的首字节)
RubySyntaxError: invalid multibyte char (UTF-8)

除全角空格之外,把全角冒号":" (U+FF1A) 当作半角冒号":" (U+003A) 使用、混入全角分号";" (U+FF1B) 之类的失误也很常见。在 JSON、YAML 这样的结构化数据中,全角冒号尤其容易成为语法错误的根源。

另外,在电商网站的商品搜索中,如果系统把"T恤" (全角 T) 与"T 恤" (半角 T) 当作不同的搜索词,搜索结果会大不相同。这里的要点是:必须对存储数据和检索查询施加同一套标准化,只处理其中一侧的话,本应命中的结果反而会匹配不上。

编程中的全角半角转换

在编程中经常需要进行全角半角转换。Unicode 中全角 ASCII 字符 (U+FF01~U+FF5E) 与半角 ASCII 字符 (U+0021~U+007E) 之间有固定的偏移量 (0xFEE0),可以通过简单的数学运算进行转换。

不过,片假名的转换要复杂得多:半角片假名将浊音符号 (゙) 和半浊音符号 (゚) 定义为独立字符,"ガ"在半角形式下是"ガ"两个字符,因此需要额外的合成与分解处理。另外,JavaScript 的 normalize("NFKC") 虽然可以一次性完成宽度标准化,但它也会把"㍻"展开为"平成"等,产生超出预期的变换,实际使用时需要谨慎限定适用范围。本文开头的转换工具正是为了避免这类副作用,只使用明确的对照表进行转换。

CSV/TSV 与全角字符的陷阱

在数据交换中广泛使用的 CSV (Comma-Separated Values) 格式里,全角逗号"," (U+FF0C) 与半角逗号"," (U+002C) 混用会引发严重问题。多数 CSV 解析器只把半角逗号识别为分隔符,因此含全角逗号的字段不会被切分,数据列随之错位。

同样,在 TSV (Tab-Separated Values) 格式中,如果用全角空格代替制表符,列的分隔也无法被正确识别。用 Excel 打开 CSV 时若出现乱码或列错位,就应当怀疑混入了全角字符。

URL 编码与全角字符

当 URL 中包含全角字符时,百分号编码 (RFC 3986) 会把每个字节转换为 %XX 形式。在 UTF-8 下占 3 字节的日文字符会膨胀成 %E3%81%82 这样的 9 个字符。

例如"东京都"这 3 个字符,在 URL 中会变成 %E4%B8%9C%E4%BA%AC%E9%83%BD (27 个字符)。考虑到 URL 的长度限制 (一般为 2,048 个字符),含大量全角字符的 URL 很快就会触及上限。在文件名或目录名中使用日文时,设计上必须把这种膨胀考虑在内。

专业人士实践的全角半角管理技巧

以文本为业的专业人士,用下面这些技巧把全角半角问题挡在发生之前。

  1. 启用文本编辑器的"显示不可见字符"功能。在 VS Code 中设置 editor.renderWhitespace: "all",全角空格就能在视觉上被区分出来。再启用 editor.unicodeHighlight.ambiguousCharacters: true,Ambiguous 类别的字符也会被高亮。
  2. 用正则表达式一次性检出全角英文字母和数字。用 [A-Za-z0-9] 搜索全角英数字,并准备好转为半角的脚本,效率会很高。
  3. 在输入表单中,于服务器端实现自动转换处理。即使用户以全角输入,系统侧也会标准化为半角,从而避免报错。
  4. 善用日文输入法 (IME) 的快捷键。Windows 下按 F8 转为半角片假名,按 F10 转为半角英数字;Mac 下按 Ctrl+; 默认转为罗马字 (半角英数字),要得到半角片假名,前提是先在"输入法"设置中启用半角片假名的候选 (2026 年 8 月时点)。
  5. 用 Git 的 pre-commit 钩子检出全角空格。以 grep -rn $'\xe3\x80\x80' 一次性检出仓库内的全角空格,在提交前发出警告,这种机制很有效。

Web 表单中全角半角自动转换的实现模式

在日本的 Web 服务中,电话号码、邮政编码、电子邮件地址等输入字段广泛实现了全角到半角的自动转换。下面介绍代表性的实现模式。

用 JavaScript 实现全角英数字到半角转换的基本逻辑,利用的是 Unicode 码位的差值。全角英数字与符号 (U+FF01~U+FF5E) 与对应的半角 ASCII 字符 (U+0021~U+007E) 之间相差 0xFEE0。

function toHalfWidth(str) {
  return str.replace(/[!-~]/g, ch =>
    String.fromCharCode(ch.charCodeAt(0) - 0xFEE0)
  ).replace(/ /g, ' ');
}

这个函数把全角英数字和符号转为半角,同时也把全角空格转为半角空格。不过,全角片假名到半角片假名的转换涉及浊音符号和半浊音符号的处理,相当复杂,建议另外使用现成的库。

在 HTML 的 input 元素上,可以用 inputmode 属性来控制输入模式,取代已废弃的 CSS ime-mode 属性。指定 inputmode="numeric" 后,移动端会显示数字键盘,从而降低全角输入的风险。

用正则表达式判定全角半角的实践

判定全角与半角时,利用 Unicode 码位区间的正则表达式很有效。需要先说明一点:East Asian Width 并不在正则表达式的 \p{...} 所能引用的属性之列,写不出 \p{Wide} 这样的形式,因此只能明确列出码位区间。下面按 East Asian Width 的类别,把标点 (U+3000~U+303F)、平假名 (U+3040~U+309F)、片假名 (U+30A0~U+30FF)、CJK 统一汉字 (U+4E00~U+9FFF)、全角形 (U+FF01~U+FF60)、半角片假名 (U+FF61~U+FF9F) 分别写成区间。

// 检出全角字符 (Wide + Fullwidth)
const fullwidthPattern = /[ -〿぀-ゟ゠-ヿ一-鿿!-⦆]/;

// 检出半角片假名
const halfwidthKatakana = /[。-゚]/;

// 只检出全角英数字 (U+FF10~U+FF19、U+FF21~U+FF3A、U+FF41~U+FF5A)
const fullwidthAlphaNum = /[0-9A-Za-z]/;

如果要在存入数据库之前统一全角半角,NFKC (Normalization Form Compatibility Composition) 标准化很有效。在 JavaScript 中,"A".normalize("NFKC") 会把全角的 A 转换为半角的 A。但 NFKC 也会把 ㍻ 展开为 平成 等,产生并非本意的变换,因此需要慎重评估适用范围。

灰色地带字符

难以简单归类为全角或半角的字符,其实分属两个不同的系统。一个是宽度本身会随环境改变的 A (Ambiguous,不确定宽度) 系:这类字符在 Unicode East Asian Width 属性中被归为 A,在不同的终端和编辑器中可能显示为单倍宽度,也可能显示为双倍宽度,希腊字母 α 和部分西里尔字母就属于这一系。另一个是映射系:宽度在规范上早已确定,但外观几乎相同的另一个码位同时存在,于是在编码转换的环节被混为一谈。

映射系的典型例子是波浪号 〜 (U+301C) 与全角波浪线 ~ (U+FF5E)。两者外观几乎相同,但在 Unicode 中是不同的字符,而且宽度在规范上都属于较宽的一侧 (East Asian Width 依次为 W 和 F),并不是宽度不确定。真正的麻烦出在映射上:Windows 的 Shift_JIS 实现曾把波浪号 (U+301C) 映射到全角波浪线 (U+FF5E),导致跨操作系统交换文本时出现乱码,这一问题被称为"波浪号问题"。

日元符号 ¥ (U+00A5) 与反斜杠 \ (U+005C) 同样属于映射系。两者的 East Asian Width 都是 Na (半角宽度),与全角的 ¥ (U+FFE5) 是彼此不同的字符。混乱的根源在于 JIS X 0201 把日元符号分配到了 ASCII 反斜杠的位置 (0x5C),于是在日语环境的某些字体中两者显示为同一形状。

本文开头的转换工具遵循这一历史教训:波浪号 (U+301C) 不做转换,只转换全角波浪线 ~ (U+FF5E) ⇔ ~ (U+007E);日元符号按 ¥ (U+FFE5) ⇔ ¥ (U+00A5)、反斜杠按 \ (U+FF3C) ⇔ \ (U+005C) 分别处理,绝不混淆外观相似的字符。

数据库中统一全角半角的最佳实践

  1. 输入时标准化:在应用层于 INSERT 进数据库之前施加 NFKC 标准化,全角英数字到半角英数字的转换会自动完成。
  2. 检索时标准化:对检索查询施加同样的标准化,吸收存储数据与检索条件之间的写法差异。MySQL 中使用 COLLATE utf8mb4_unicode_ci 即可实现不区分全角半角的排序规则比较。
  3. 列设计:明确 VARCHAR 的长度指定是按字数 (MySQL) 还是按字节数 (Oracle),在 UTF-8 环境下要按全角 1 个字符 = 3 字节来设定字节上限。
  4. 索引设计:若需要不区分全角半角的检索,准备一个存放标准化后取值的独立列,并对该列建立索引,是效率较高的做法。

总结

全角与半角的区别不只是外观问题,它直接关系到字数统计、字节数计算、数据库设计、URL 设计以及编程的正确性。其根底是 JIS X 0201/0208 的历史沿革,以及 Unicode 的 East Asian Width 属性这一技术规范。准确掌握各编码下的字节大小差异,并善用 NFKC 标准化、正则表达式检出这些实用技巧,就能把全角半角引发的问题挡在发生之前。理解不同系统的计数方式差异、统一使用规范,是避免相关问题的关键。使用字符计数器可以分别显示全角和半角字符的数量,帮助您在核对全角半角构成的同时进行准确的字数管理。

分享这篇文章