全角字符到底有哪些

老是有人弄什么一个中文字算两个西文字这种问题,一般而言这种问题是极其愚蠢的。为什么一个中文字要算两个西文字呢?

有些人做前端算宽度(比如显示标题要截掉一些字以免放不下),但是在绝大多数场景下,使用比例字体的西文的宽度是不等宽的,也不可能是中文字的一半宽。况且除了中文、西文,还有其他文字呢?比如藏文、维吾尔语等,你算一个还是两个?【不要跟我说你只考虑中英文,连少数民族的语言文字都他妈不支持,鸟语倒支持个起劲,还好意思说什么民族团结?】

对于标题截取这种需求,合理的对策是用CSS,对于CSS支持不够的,可以用脚本来计算。简单来说就是把一串字放在一个隐藏容器里量一下,然后截取到指定长度以内。如果用Canvas Text API,更是非常简单的。

另一些人说是要存数据库。但是他妈谁告诉你数据库里保存的时候就是一个中文字对两个西文字?拜托补习一下基本的编码常识。一个汉字对两个英文字母那都是古老的双字节编码了。不说Unicode,GB18030-2005包含70000+字符,显然会有超过双字节的情况。如果你还在用GB2312、GBK,那问题同上,怎么存藏文、维吾尔语等……


抛开这些本身就不合理的需求,但是仍然有少数需求是需要考虑汉字的特殊性的。那就是排版。在排版中,汉字(准确说是中日韩越文字)是直接按照方块字来排的,而其他语言的字符通常要变宽处理。

那么到底哪些字符是方块呢?

如果看看输入法就知道,一直到现在我们都还有全角(Fullwidth)、半角(Halfwidth)的区分。全角就是方块字,而半角则是半个方块字。实际上这是从legacy encoding+早期等宽字体遗留下来的。在Unicode规范里,对东亚字符的这种特殊属性做了更详细的阐述,具体可参考:[url]http://unicode.org/reports/tr11/[/url]。

这里就简单的根据Unicode数据库来给出到底哪些字符是“全角字符”。

1100..115F
11A3..11A7
11FA..11FF
2329,232A
2E80..4DBF (去掉303F)
4E00..A4CF
A960..A97F
AC00..D7FF
F900..FAFF
FE10..FE1F
FE30..FE6F
FF01..FF60
FFE0..FFE7
1F200..3FFFF

以正则表达式来写就是:
/[\u1100-\u115F\u11A3-\u11A7\u11FA-\u11FF\u2329\u232A\u2E80-\u303E\u3040-\u4DBF\u4E00-\uA4CF\uA960-\uA97F\uAC00-\uD7FF\uF900-\uFAFF\uFE10-\uFE1F\uFE30-\uFE6F\uFF01-\uFF60\uFFE0-\uFFE7]/

注意,U+303F虽然是在CJK标点符号区,但是只有它却不是全角的,这个罕用符号表示半个汉字的空间。

另外U+3248到U+324F严格说也不是全角的,在Unicode规范里归为(A)mbiguous类,意思是在特定上下文里(如东亚文本里)可以是全角的,而在其他上下文里则是半角的。A类的字符还有很多,比如双引号、间隔号等,在西文字体里都有这些字符,当然也不可能是按照全角方块字来设计的。

因为实际的字符宽度取决于语言及字体选择等因素,所以我暂时并不直接将A类归入全角。只有U+3248到U+324F在大多数字体里根本都不支持,因此就马虎点按全角算了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值