常被误用的间隔号

间隔号“·”(Unicode U+00B7)是一种标点符号。在中国大陆“·”占半个字的位置,在台港澳地区“·”占一个字的位置(这里使用思源黑体)。 实务上,宋体把这个字渲染成全宽,微软雅黑把这个字渲染得太窄,都不像是半个字的位置。而大部分台湾字体厂商又把这个字渲染成半宽,反而把“.”(Unicode U+FF0E)渲染成全宽(这里使用微软正黑体),造成误用非常常见。 用途 少数民族人士或外国人的姓名(或本名与父名)之间的分界,例如: 爱新觉罗·玄烨 尼格买提·热合曼 艾萨克·牛顿 书名的卷名、篇名和章节名之间的分界,例如: 陈寿《三国志·蜀书·诸葛亮传》 王朔《起初·纪年》 诗词的诗体、词牌和题目之间的分界,例如: 苏轼《念奴娇·赤壁怀古》 陆游《七绝·示儿》 毛泽东《沁园春·雪》 会产生歧义时月份和日期之间的分界,例如: “一二·九”运动 “3·15”消费者权益日 在词语之间表示并列关系,例如: 鲁迅《狗·猫·鼠》 生活·读书·新知三联书店 相关标准 《标点符号用法》(GB/T 15834–2011) 第4.14节“间隔号”说: 标号的一种,标示某些相关联成分之间的分界。 第5.1.7节说: 间隔号标在需要隔开的项目之间,占半个字位置,上下居中,不出现在一行之首。 讽刺的是,由于这份文件使用方正排版系统生成,使用方正字库,所有的间隔号都被印刷成全宽。其他标点挤压也很糟糕,句中标点显示为半宽,句末标点显示为全宽。 《金融服务 生僻字处理指南》(JR/T 0253–2022) 第6.1.4节“少数民族姓名间隔符的输入”节说: 少数民族姓名间隔符须按照《关于在政府管理和社会公共服务信息系统中统一姓名采集应用规范的通知》(民委发〔2016〕33号文)要求的格式输入, 统一用“·”(UCS编码U+00B7,GB18030编码A1A4)。考虑到常用字符集中“实心点”字符有多个,宜在用户输入的前端检测少数民族姓名间隔符为非U+00B7的“实心点”时, 自动转换成U+00B7。 注:有些文字处理软件中U+00B7复制到其他应用有可能变成U+2022。 U+00B7在Unicode中的定义是“MIDDLE DOT”。 1 2 3 4 >>> hex(ord('·')) '0xb7' >>> chr(0xb7) '·' 顺便说一句,U+XXXX或U+2XXXX表示UCS的一个码点或字符。通用编码字符集(UCS) 标准由国际标准化组织(ISO)与国际电工委员会(IEC)制订, 编号为ISO/IEC 10646,最新版本为ISO/IEC 10646:2020。 统一码(Unicode) 是由统一码联盟依据UCS制定的可以容纳世界上所有文字和符号的编码字符集。我国现行GB/T 18030–2005与ISO/IEC 10646:2000(即第2版)保持同步,也就相当于Unicode 3.1版本。2023年8月1日即将实施的GB/T 18030–2022与ISO/IEC 10646:2017(即第5版)保持同步,也就相当于Unicode 11.0版本。 《中文出版物夹用英文的编辑规范》(CY/T 154–2017) 第6节“人名缩略翻译的处理”说: ...

November 16, 2022 · 1 min · Hanson Hu

锟斤拷

今天不是聊我新取的ID——虽然它真是很酷的一个,又来聊乱码问题了。相信每一个在非英语环境中工作的程序员都受到过乱码的困扰,做为程序员,简单的说,应始终意识到在内存中字符串是以Unicode方式表示的,在I/O时尽量使用UTF-8编码(除了在中文Windows控制台输出时不得已而使用GBK/GB18030),当遇到不可控制的外部系统使用了其他编码方式时,使用恰当的方法进行解码。 Unicode的基本多文种平面(Basic Multilingual Plane,BMP),即UCS-2,共有216=65536个字符,能够满足绝大多数使用需求,另外的补充多文种平面(Supplementary Multilingual Plane,SMP),即UCS-4,更是提供了231=2147483648个地址空间(UCS-4的首位恒为0),实际上在Unicode标准中已经定义了超过10万个字符,提供给全体地球人使用。 考虑以下Java代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 logger.info("当前JRE版本:" + System.getProperty("java.version")); logger.info("当前默认字符集:" + Charset.defaultCharset()); String str = "UTF-8字符"; byte[] bytes = {(byte) 0xC0, (byte) 0xC0}; try { byte[] b1 = str.getBytes("ISO-8859-1"); logger.info("使用ISO-8859-1编码:{}", toHexStr(b1)); logger.info("使用UTF-8解码并转为Unicode字符串:{}", new String(b1, "UTF-8")); String s1 = new String(bytes, "UTF-8"); logger.info("使用UTF-8解码并转为Unicode字符串:{}", s1); b1 = s1.getBytes(); logger.info("使用UTF-8编码:{}", toHexStr(b1)); logger.info("使用GB18030解码并转为Unicode字符串:{}", new String(b1, "GB18030")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } 输出为: ...

April 23, 2011 · 1 min · Hanson Hu