日语页面上那行小字是给孩子读的,抽答案的程序把它当成了正文
本文目录
- 为什么日语页面上会多出一行没人当回事的小字?
- 从一家日本儿童文具站的商品名说起
- 这行小字有三个来源,都不是装饰
- 它跟你熟悉的那几种排版手段完全不是一类
- 同一个位置摞了两串,浏览器怎么显示,程序怎么读?
- 三个标签分别管什么
- 回退括号那对括号,藏着整件事的关键
- 取一段文字,你以为取到的是哪一串
- 粘出来的那个词,在这门语言里根本不存在
- 这一层字是在哪一步被拼成一串的?
- 五个位置,各自出错的方式不一样
- 五处里面,只有一处会被人看见
- 它为什么在英语站上从来不是个问题
- 这跟看不见的字符、跟罩错词的标记差在哪儿?
- 三种问题,三个不同的层
- 一个能删,一个不能删,这个差别决定了解法
- 跟版面手段那一篇的关系
- 注音不只在正文里,它还在表单和数据源里各占一份
- 日本表单里那个假名字段是独立存在的
- 商品数据源里的隐藏读音属性
- 三种形态各归各的地方
- 阿拉伯语和希伯来语头顶那些点,跟这是同一件事吗?
- 方向正好相反的一对
- 缺信息那一半,早就有人讲过了
- 一个在字符内部,一个在标签外部
- 关键词表要不要把注音那一串也收进去?
- 先问用户会不会这么打
- 收进去和收错了,差在一个空格上
- 假名写法本身还有两派
- 哪些位置可以留注音,哪些位置一个都不能留?
- 能留的位置:正文与商品描述
- 不能留的位置:标题、描述、替代文本
- 最容易被忽略的是结构化数据
- 锚文本这一处要分情况
- 不懂日语,怎么测出自己的页面被拼成了什么样?
- 第一步:把眼睛看到的和程序取到的并排放
- 第二步:在控制台里数一遍
- 第三步:拿三条管道各取一次
- 一份可以照着走的注音层处理清单
- 先分流,再谈别的
- 字段级的取舍表
- 验收的时候看什么
- 哪些事不归语言层,一句话交出去
- 常见问题解答
- 不做日本市场,这一篇跟我有关系吗?
- 直接把注音全删掉,是不是最省事?
- 用回退括号那个标签,是不是就万事大吉了?
- 站内搜索到底该索引哪一串?
- 这一层会不会被判成关键词堆砌?
- 为什么校验工具一个警告都没报?
- 什么时候该把这件事排进日程?
- 权威参考资料
摘要:日语商品页上那行浮在汉字头顶的小假名,是给读不出这个字的人准备的。屏幕上它规规矩矩待在上面,可程序去取这一段文字的时候,取回来的是汉字和假名首尾相接粘成的一串,页面上从来没有人写过那个词。页面上绝大多数文本,一个位置只有一串字符,注音是唯一一处同一个位置摞了两串,而且两串都是给人看的。这一篇讲这层字怎么被拼错、错在哪几个位置,以及不懂日语的人怎么用十行代码测出自己的页面被拼成了什么样。
为什么日语页面上会多出一行没人当回事的小字?
从一家日本儿童文具站的商品名说起
先说一件真事。
那是一家做日本市场的儿童文具站,主推小学生用的书包、笔袋和练习本。
商品名写得很讲究,汉字上面全都规规矩矩标了假名。
这是这个品类的规矩,不是设计师一时兴起。
面向小学生的东西,汉字要按学年配当来控制,超纲的字得给出读音。
页面在浏览器里看毫无问题,两行字上下错落,读着舒服。
问题出在别处:站内搜索里搜商品名一个结果都出不来,导出的商品表里商品名全是一串谁也读不懂的东西,投给比价平台的数据源被判成了乱码。三处故障,同一个原因,而这个原因在页面上根本看不见——它只在文字被程序取走的那一瞬间才成立。
保哥当时接手看了不到十分钟就找到了,因为这类事故的形状太固定了。
这三处故障还有一个共同的时间特征:它们都不是上线当天暴露的。站内搜索没结果被当成了收录还没跟上,导出表乱码被当成了编码没选对,平台打回被当成了字段格式问题。三条线各自查了两周,谁也没想到去问另外两条线在查什么。
这行小字有三个来源,都不是装饰
先把它是什么说清楚。
浮在汉字上方那一行小假名,日文里叫振假名,中文习惯叫注音。
它出现在页面上,通常出于三种理由中的一种。
第一种是法规和规范要求。日本内阁告示的常用汉字表划出了一般社会生活里使用汉字的范围,公文和面向大众的说明文字通常按它走,表外的字要么换写法,要么标读音。
第二种是年龄。日本小学各学年的汉字配当把一千多个汉字分摊到六个学年,面向低年级的商品,超出该学年范围的汉字几乎一定要注音。
第三种是人名地名和难读词。日本人的姓名同一串汉字可以有好几种读法,表单和文书里因此常年并存两个字段,一个填汉字,一个填假名。
三种来源的共同点是,注音不是可有可无的修饰,它承担着实际功能。既然承担功能,它就不会因为工程上不方便而消失,你只能接住它。
这三种来源还有一个共同点常被忽略:决定要不要注音的人,跟决定页面怎么取文本的人,从来不在同一个会议室里。前者是内容和法务,后者是前端和数据。中间那道缝隙有多宽,这一层出问题的概率就有多高。
它跟你熟悉的那几种排版手段完全不是一类
加粗、斜体、下划线,这些手段改的是同一串字符的显示方式。
字号、颜色、字间距,改的也是同一串字符。
注音不一样,它往版面上放了第二串字符。
这第二串字符不是样式,是内容,它有自己的文字,有自己的长度,能被选中,能被复制。
换句话说,页面上绝大多数文本,一个位置只有一串字符;注音是唯一一处同一个位置摞了两串,而且两串都是给人看的。这句话是本文所有结论的来源。你熟悉的所有文本处理工具、抽取逻辑、导出脚本,背后都默认一个位置只有一串字。这条默认假设在拉丁字母的世界里从来没被挑战过,因为那个世界里确实如此。
还有一个更直接的分辨办法:把样式全部关掉,看那段文字还剩什么。加粗斜体关掉之后字一个不少,注音关掉之后要么那串假名还在、只是不再浮在上面,要么它跟正文挤成了一行。凡是关掉样式还留在页面上的,都是内容不是格式。
同一个位置摞了两串,浏览器怎么显示,程序怎么读?
三个标签分别管什么
浏览器显示这层字靠三个标签配合。
外面那个是注音标注元素,它把被注音的字和注音本身框在一起。
里面那个是注音文本元素,装的是浮在上方的小字。
还有一个是回退括号元素,专门给不支持这套显示的环境准备,它装的是一对圆括号。
三者的分工很清楚:第一个划范围,第二个放注音,第三个负责在显示不出来的时候把注音变成括号里的一段说明。第三个标签的存在本身就说明了一件事——这套机制的设计者从一开始就知道,会有环境把两串字读成一串,所以预先给了一个降级方案。降级方案的存在是个信号,它等于承认了这一层不总是能被正确处理。
这三个标签之间还有一层嵌套关系值得注意:注音文本元素必须待在注音标注元素里面,不能单独存在。这条约束的实际后果是,你没办法用选择器把注音那一串整体挪走而不动它的容器,分流只能在取值那一步做,不能靠改结构做。
回退括号那对括号,藏着整件事的关键
回退括号这个设计值得单独说两句。
它的意思是:如果你的环境读不懂上下两层,那就把注音放进括号,跟在被注音的字后面。
于是同一段内容有了两种正确的读法,一种是上下两层,一种是括号并排。
两种读法都对,可它们产出的字符串完全不同。
问题在于,绝大多数程序既不显示上下两层,也不会替你补括号,它只是把所有文字节点按顺序连起来。不显示也不补括号的结果,是两串字直接首尾相接,中间什么都没有。汉字后面紧跟着这个汉字的读音,读起来像一个人说话结巴了一下。
这个信号还有一层意思:设计者预料到的是显示环境读不懂,没有预料到的是取值环境根本不看显示。二十年前那批环境是文本浏览器和老旧终端,今天真正大量读页面的是各类抓取和导出程序,而它们对回退方案完全无感。
这里还有一个时间上的巧合值得一提:这套标记进入正式规范的年代,正好是网页内容主要被人眼消费的年代。等到大量程序开始批量读取网页文本,它已经定型多年,没有人回过头来重新审视那条降级路径够不够用。
取一段文字,你以为取到的是哪一串
具体到代码这一层,事情更清楚。
取节点文本内容的那个属性,会把所有后代文字节点原样拼起来,注音那一串照收不误,这一点在文本内容属性的文档里写得很明白。
另一个取渲染后文本的属性会考虑样式,行为上更接近人眼看到的结果,但两者的差异在各家浏览器里并不完全一致,渲染文本属性的文档里专门解释了这种差异从哪来。
更麻烦的是,你的商品数据往往不是从浏览器里取的,而是从数据库、从接口、从导出的表格里取的,那些地方连样式的概念都没有。
所以同一个商品名,在页面上、在剪贴板里、在导出的表里、在投给平台的数据源里,可能是四个不同的字符串。四份数据谁也不知道其他三份长什么样,而校验的时候人们只看页面。
要看清这件事,可以拿一段带注音的文字做个小实验:先用鼠标选中,看选区高亮的范围包不包括上面那行小字。多数浏览器里是包括的,这说明在浏览器眼里它们本来就是同一段文本,只是被排到了两行上。
粘出来的那个词,在这门语言里根本不存在
这里有个容易被忽略的细节。
拼接产出的不是一个错别字,是一个不存在的词。
它由正确的汉字和正确的假名组成,每个字符都合法,组合起来却谁也不认识。
日语的分词器面对它会给出一个荒唐的切法,因为词典里没有这条。
这跟拼错一个字母完全不同:拼错的词至少还落在拼写纠错能兜住的范围里,而这种粘出来的串形态上完全合法,只是没有意义,任何以合法性为判据的检查都放它过去。这也是为什么这类问题总能活很久——所有的校验器都觉得它没毛病。日语本来就不靠空格分词,切分完全交给词典和引擎,这件事在日语三套文字混排的关键词写法那篇里展开过,这里只补一句:注音制造出来的那些串,是词典里最不可能收录的一类。
这类串还有一个特点会误导排查方向:它们的长度看起来很正常。汉字加上自己的读音,总长度往往还落在商品名的常见区间里,字数校验和字段长度限制都不会报警。如果它们长得离谱,反而早就被人发现了。
还有一个判断这类串有没有混进来的土办法:把一批商品名按长度排序,看长度分布有没有出现两个峰。带注音的那一批会整体偏长,在分布图上鼓出一个小包。看得出这个包,就说明数据里混着两种形态的商品名,而不是同一种。
这一层字是在哪一步被拼成一串的?
五个位置,各自出错的方式不一样
把链路一段段拆开看,出错的位置一共五处。
第一处是用户复制。选中一段带注音的文字复制出去,粘贴到别处得到的通常就是粘连串。
第二处是站内搜索的索引。索引程序取文本时几乎都用最原始的那种取法,注音一并进了索引。
第三处是数据导出。商品表导出成表格或者接口,出来的是拼接后的那一串。
第四处是抓取与摘录。外部程序读你的页面,读到的是拼接串,摘出来当作直接答案展示的时候也是。
第五处是各类文本统计。字数、可读性、关键词密度这些数字全都因此偏高,而且偏得很有规律。
这五处还可以按发现难度重新排一次序:越靠近用户的越容易被发现,越靠近数据管道深处的越难。而商业价值的排序恰好相反,管道深处那几处直接决定商品能不能被检索、能不能上架。难发现和高价值这两条,在这里是重合的。
五处里面,只有一处会被人看见
这五处的严重程度并不一样。
真正致命的是第二处和第三处,因为它们直接决定用户搜不搜得到、平台收不收你的数据。
而唯一有可能被人肉眼发现的是第一处,因为复制粘贴之后那串字就摆在眼前。
其余四处全在系统内部完成,没有任何界面会把结果展示给你看。
于是就有了这类事故的典型形态:用户抱怨搜不到,运营查页面一切正常,双方各自确信自己没错,因为他们看的根本不是同一份字符串。这种争论通常要持续好几周,直到有人偶然把商品名粘进记事本。
要打破这种僵局,最快的办法不是继续解释,而是当场做一次复制粘贴给对方看。这件事的说服力在于它不需要任何专业知识,双方看到的是同一屏幕上的两串字。技术争论一旦能被还原成一个五秒钟的动作,通常就结束了。
它为什么在英语站上从来不是个问题
顺手把这条讲清楚,免得有人觉得这是小题大做。
英语内容里没有这一层,所以整条工具链从来没有为它做过任何准备。
拼接所有文字节点这个做法,在只有一串字的语言里永远是对的。
它不是一个有缺陷的实现,它是一个在特定假设下完全正确的实现。
这跟大小写转换那件事同一个道理:一个函数如果没有语言参数,它不是通用的,它是选了默认值的。这条判据在小语种大小写折叠的那些坑里已经验证过一次,这里第二次成立,只不过这回被选中的默认值不是英语的字母表,而是英语的版面结构。
这条还能推出一个采购层面的建议:评估任何一款内容工具时,不要问它支不支持日语,要问它取文本的时候怎么处理注音标记。前一个问题所有厂商都会答支持,后一个问题能答上来的很少,而后者才是真正的分水岭。
这跟看不见的字符、跟罩错词的标记差在哪儿?
三种问题,三个不同的层
小语种页面上有三类长得很像的麻烦,值得摆在一起比一比。
第一类是不可见字符,比如软连字符和零宽空格,它们藏在字符串里,屏幕上完全看不出来。
第二类是内联标记漂移,加粗和斜体在译文里罩错了词,屏幕上看得见,但看着很正常。
第三类就是本文这一层,屏幕上看得见,看着也正常,而且它比前两类多了一整串真实文本。
三者的共同点是都能通过所有自动校验,区别在于前两类是字符串被污染或者被标错,这一类是字符串本身多了一段。多出来的那一段不是杂质,它是内容,删掉是错的。这就把解法逼进了一条更窄的路。
三类问题还有一个共同的成因:它们都诞生在版面需求和数据需求打架的地方。断行是为了好看,强调是为了显眼,注音是为了读得出,三件事都由内容侧提出,都在标记层落地,而承担后果的全是下游的数据管道。
一个能删,一个不能删,这个差别决定了解法
把差别再说透一点。
软连字符可以删,删掉之后把断行交给样式层去做,页面照样好看,这件事在断行那一篇里给过完整的选型顺序。
加粗罩错了词可以改,把强调从版面手段换成句法手段,意思一点不损失。
注音删不掉。删了小学生就读不出那个字,删了姓名字段就填不了,删了法规要求就没满足。
所以这一层的处理方向跟前两类正好相反:不是想办法把它从字符串里清出去,而是想办法让每一条管道各自拿到它该拿的那一份。这是一道分流题,不是一道清洗题。想明白这一点,后面的所有具体做法就都顺了。
分流题和清洗题的区别还体现在验收方式上。清洗题的验收是查残留,扫一遍看还有没有漏网的字符即可。分流题的验收是查去向,得逐条管道确认它拿到的是哪一份,没有任何单点检查能替你完成。这也是它更费事的原因。
跟版面手段那一篇的关系
再补一句边界。
标记漂移那件事里,问题出在标签罩住的词跟原文不是同一个,解法是把强调改成句法结构,具体做法在译文里加粗错位的排查办法那篇里。
本文这件事里,标签罩住的位置一点没错,多出来的是标签里面的另一串文字。
两者唯一的共同点是都涉及内联标签,此外没有任何交集。
如果说标记漂移是把重音放错了地方,那注音就是同一个音同时被两个人唱着,而录音设备只有一条轨。前者调整位置就能修好,后者得先决定录哪一条。
再补一个反向的关系。标记漂移那件事里,译员是问题的来源,因为标签的位置由人摆。注音这件事里,译员完全无关,注音是模板或者编辑加的,出错的位置在取值环节。前者要靠改流程管人,后者只要改一次取值方式。
注音不只在正文里,它还在表单和数据源里各占一份
日本表单里那个假名字段是独立存在的
很多人以为这是排版问题,其实它在数据结构里也有位置。
日本的注册表单和收货地址表单,姓名通常拆成两组字段。
一组填汉字姓名,另一组填假名读音,后者常常还要求全用片假名。
这两组字段在数据库里是两列,不是一列的两种形态。
这件事的意义在于,注音在这里已经被当成独立数据处理了,而在正文里它还是内联的。同一个东西在你的系统里存在两种形态,一种规规矩矩有自己的列,一种混在一段文字中间,出问题的永远是后一种。姓名字段本身的排布规则跟别的市场差在哪,匈牙利语姓在前那一类字段设计里讲过一次,可以对照着看。
这个字段还有一个被低估的用途:它是你手上唯一一份由用户亲手填写的读音数据。用户自己填的读音,比任何自动转换出来的都可靠,积累一段时间之后,它可以直接拿来校准你对同一批汉字读法的判断,这份数据别的地方买不到。
商品数据源里的隐藏读音属性
还有一处更隐蔽。
日本客户给你的商品表格,通常是一份电子表格文件。
表格软件里的日语单元格有一个专门的读音属性,输入汉字时输入法把读音顺手存了进去,界面上默认不显示,有专门的函数可以把它取出来,微软的读音函数说明里描述了它的取法。
这个属性在另存为纯文本格式的时候会整块丢掉。
于是同一份商品表,用不同方式导出会得到不同的信息量,而丢掉的那一份恰好是排序和检索最需要的。日本的商品列表按五十音顺排序,靠的正是这一列,一旦丢失,排序就只能退回按字节比大小,出来的顺序在日本人眼里毫无道理。
这里还有一个更常见的丢失路径:表格文件在不同软件之间转一手。用开源办公软件打开再存回去,或者用脚本读取再写出,这个隐藏属性通常都不会被保留。而这两件事在数据对接里天天发生,谁也不会觉得自己丢了东西。
顺带说一句检查办法:拿到日方给的表格之后,先另存一份纯文本,再另存一份保留格式的,两份文件大小差得越多,通常说明藏在里面的附加属性越多。这个粗糙的判断只要两分钟,比逐列核对快得多。
三种形态各归各的地方
把三处归纳一下。
正文里,注音是内联的,跟被注音的字摞在一起。
表单里,注音是独立字段,有自己的列和自己的校验规则。
数据源里,注音是单元格的隐藏属性,取不取得到看你用什么方式读。
三种形态在同一个项目里同时存在,而团队里通常有三拨人分别负责,谁也不知道另外两处也有这个东西。把这三处画在同一张图上,是这类项目开工时最值钱的半小时。画完之后你会发现,很多人以为的排版细节,其实横跨了前端、表单和数据管道三条线。
这张图还有一个立竿见影的用处:它能挡住一类常见的重复劳动。三条线各自发现问题之后,往往会各自加一段清洗代码,三段代码规则不一致,互相之间还会打架。有了这张图,清洗只在一处做,其余两处只管取值。
阿拉伯语和希伯来语头顶那些点,跟这是同一件事吗?
方向正好相反的一对
这个问题问得好,因为答案是既是也不是。
阿拉伯语和希伯来语平时不写元音,元音靠读者根据上下文补。
需要的时候可以把元音符号标出来,标在字母的上下,宗教文本、儿童读物、教材里常见。
所以这两门语言的默认状态是不标,标是例外。
日语的默认状态是不注音,注音也是例外。到这一步两者看起来是一回事。真正的差别在于,不标元音会让一个词有多种可能的读法,而多标了注音会让一段文字多出一串字符。前者是信息不足带来的歧义,后者是信息过量带来的粘连。一个是缺,一个是多,处理方向完全相反。
缺和多这两种状态还有一个不对称之处:缺信息可以靠上下文补回来,人和机器都能补一部分;多出来的那一串却没有任何人能判断它该不该在这里,因为它本身完全合法。补是有希望的,删是有风险的,所以后者反而更棘手。
缺信息那一半,早就有人讲过了
信息不足那一半不在本文的范围里。
不写元音会造成多少歧义、词根三辅音怎么变成可用的选词方法,希伯来语不标元音的选词办法那篇讲得很细。
阿拉伯语这边同一个字母的几种写法怎么把词表拆散,在阿拉伯语词根与破碎复数的词表拆分里也有专门一节。
本文只接手另外那一半:当这些符号真的被标出来之后,你的字符串会发生什么。
结论跟日语惊人地一致——标了元音符号的词和没标的词,在字节层面是两个不同的字符串,精确匹配对不上,去重对不上,排序也对不上。阿拉伯语与波斯语排版需求文档里对这些符号的排布有专门章节,可以看到它们在版面上的位置有多讲究。
这条分工线也提醒了一件事:同一门语言在本站可能被拆进好几篇里讲,不是因为写不完,而是因为机制不同。判据是这两件事出问题的时候,排查会走进不同的层。走进同一层的合成一篇,走进不同层的就得分开。
这条分工线还有一个实际好处,就是内链好写。同一门语言分在几篇里,彼此之间的引用关系天然成立,读者顺着链接走一圈能拿到完整的图景,而每一篇又都只回答一个问题,不至于写成一份什么都讲一点的说明书。
一个在字符内部,一个在标签外部
不过技术处理上,两者差着一层。
阿拉伯语和希伯来语的元音符号是组合字符,它们直接跟在字母后面,属于同一个字符串,这一类字符的行为在组合标记常见问题里有系统说明。
日语的注音是独立的标签内容,它跟被注音的字之间隔着标记结构。
前者要在字符层做归一化处理,后者要在标记层做分流处理。
所以同一句话在两边的落地办法完全不同:阿拉伯语那边你要决定入库时剥不剥符号,日语这边你要决定取文本时收不收注音。剥符号是有损的,收不收注音是可逆的,这一点上日语的处境反而好一些。希伯来语那些元音点的独立码位可以在希伯来文码表里逐个查到。
这个差别还决定了谁来动手。字符层的归一化通常由后端或者数据库配置负责,一旦定下来全站生效;标记层的分流由前端和取值代码负责,得逐个位置改。前者是一次决策,后者是一批改动,排期的时候要分开估。
关键词表要不要把注音那一串也收进去?
先问用户会不会这么打
这个问题的答案取决于品类,不是取决于语言。
日语用户在搜索框里打字,几乎总是先打假名再转换成汉字。
转不转换,取决于这个词在他脑子里的标准形态是什么。
商品品类词绝大多数会被转换成汉字,因为那是通行写法。
但有几类词不会:儿童向的商品名、拟声拟态词、部分外来语,用户打完假名就直接回车了。判据不是这个词有没有汉字写法,而是用户脑子里那个词长什么样。这跟工具给的搜索量没关系,工具那点数据在小语种上本来就靠不住,替代办法在工具没数据时的三条补救路径里写过。
还有一个反直觉的现象:越是简单常用的商品词,用户越倾向于打完假名就直接回车,因为转换那一步本身要多按一次键。反倒是那些容易混淆的词,用户会耐心转换成汉字以确保搜的是对的东西。省事和求准这两股力,在不同的词上胜负不同。
收进去和收错了,差在一个空格上
假设你决定收。
要收的是注音本身,也就是那串独立的假名。
不能收的是拼接产物,也就是汉字紧跟着假名的那一串。
前者是用户真的会打的词,后者是这个世界上没有人会打的字符串。
可惜的是,如果你的词表是从站内搜索日志或者从页面文本自动扒下来的,扒到的十有八九是后者。词表里凡是出现汉字直接连着自己读音的条目,一律是污染,不是需求。这一条可以写成一行正则挂在词表的入库校验上,成本极低。
这条校验规则还能顺手抓到另一类问题。除了汉字紧跟读音,还有一种是同一个词在词表里连续出现两次、第二次多带了一小段假名尾巴。这两种形态都指向同一个源头,也就是某条自动采集管道用了最原始的取文本方式。
这条规则还有一个副产品:它能顺手把词表的来源标记出来。凡是被这条规则拦下来的条目,几乎都来自自动采集那一路,人工整理的词表几乎不会产生这种形态。拦截日志本身就是一份来源质量报告。
假名写法本身还有两派
还有一层。
就算决定收假名,同一个读音也有平假名和片假名两种写法。
外来语按规矩用片假名,固有词用平假名,可用户不总是按规矩来。
注音这一层通常用平假名,而表单里的读音字段常常要求片假名。
于是同一个词的读音在你的系统里可能同时以两种字符存在,这两种字符在字节上毫无关系。三套文字并存带来的写法分叉,日语关键词的写法覆盖那篇有完整的展开,本文只提醒一句:注音这一层会把已经分叉的写法再分一次。
两派写法在检索侧的表现也不一样。片假名在日语里天然带着外来语和商品名的气味,平假名带着口语和儿童向的气味,同一个读音写成两种,落到的查询意图并不完全重合。所以这不只是字符层的分叉,它还是一次轻微的意图分叉。
哪些位置可以留注音,哪些位置一个都不能留?
能留的位置:正文与商品描述
先说能留的。
正文段落里可以留,这本来就是这套标记设计出来的用武之地。
商品描述里可以留,前提是导出数据源的时候走的是另一条管道。
面向儿童和面向老年人的说明性内容里应该留,这是可读性问题。
判据很简单:这段文字只被人眼消费,就可以留;它同时要被程序消费,就得先想清楚程序拿到的是哪一串。绝大多数纠纷都源于第二种情况被当成了第一种。
还有一个容易走偏的地方:有人会把这条判据理解成正文随便写。正文虽然能留注音,但正文同样会被摘取、被复制、被拿去做内容分析。能留的意思是不必因为数据管道而牺牲可读性,不是这一段就此不再产生任何字符串。
不能留的位置:标题、描述、替代文本
再说不能留的。
页面标题标签里不能留,标题在搜索结果里是纯文本,注音进去就是粘连串。
元描述里不能留,理由相同。
图片的替代文本里不能留,替代文本本来就是给读不到图的人和程序准备的,塞进去的注音会被读两遍。图片这一层在小语种站上本来是最容易捡的流量,具体写法在非拉丁文字站的图片替代文本写法里有整套流程。
网址里更不能留,这一层的取舍在本地字母网址与拉丁转写的四种组合里单独讨论过。
这几处还有一个共同特征:它们的值往往不是人手写的,而是模板从别处拼出来的。标题从商品名拼,描述从卖点拼,替代文本从商品名加属性拼。只要源头那个商品名带着注音,这几处就会同时中招,而且错得一模一样。
最容易被忽略的是结构化数据
有一个位置几乎所有人都会漏。
结构化数据里的商品名、品牌名、描述这些字段,值经常是直接从页面元素里取的。
取法一旦用了最原始的那种,注音就跟着进了标记。
而结构化数据是全站唯一写错了没人会投诉的地方,因为它不显示给任何人看。
这一层的字段该怎么分类处理,小语种结构化数据的三类字段那篇给过一张表,本文只补一条:凡是从页面元素取值的字段,都要单独确认一遍取到的是哪一串。
结构化数据这一处还有一个额外的坏处:它是被外部程序原样取走的字段。别的地方出了粘连串,至少还有人可能看到;这里出了粘连串,字面上就等于你亲口告诉外部这个商品叫这个名字。自己声明的错误,比被误读的错误更难解释。
锚文本这一处要分情况
最后一处是内链的锚文本。
锚文本里出现注音,本身不算错,因为它也是给人读的。
但锚文本会被各类工具当成纯文本收集,收集到的会是粘连串。
所以稳妥的做法是锚文本里不放注音,把注音留在锚文本外面的那句话里。锚文本本身该怎么划边界,屈折语那边的规则在锚文本在屈折语里的变形处理里有六条位置判据,日语这边没有变格问题,但边界规则是通用的。
还有一种折中做法值得一提:锚文本用纯净形态,注音放在锚文本前后的句子里。这样读者依然能读出那个词的音,工具收集到的锚文本也是干净的。这类把两种需求错开摆放的做法,在这一层里往往比二选一更实用。
不懂日语,怎么测出自己的页面被拼成了什么样?
第一步:把眼睛看到的和程序取到的并排放
这件事不需要懂日语,只需要会做一次对比。
打开一个带注音的页面,选中一段文字,复制,粘贴到任何一个纯文本编辑器里。
然后把这段文字在页面上的样子截个图,两边并排。
如果粘贴出来的字数明显多于屏幕上那段,多出来的就是注音。
这一步能在三分钟内给出确定的答案,而且不需要任何工具。整件事最难的从来不是技术,是想到要做这个对比。
这个对比还有一个变体更适合拿给管理层看:把同一段文字分别贴进纯文本编辑器和聊天窗口,两处显示的结果通常还不一样。两三个窗口一并排,一句话都不用解释,对方自己就会问这是怎么回事。
这个动作还有一个副作用值得提前说明:一旦大家看到粘连串,往往第一反应是把注音全部去掉。这时候需要有人及时把话接住,说明这一层不能删,要解决的是取值方式。否则一个显示问题会被顺手改成一个合规问题。
第二步:在控制台里数一遍
要更精确一点,就在浏览器控制台里跑两行。
取那个元素的文本内容属性,看长度是多少。
再把元素里所有注音文本元素的内容单独取出来,看长度是多少。
两个数字一减,就知道注音在这段文字里占了多大比重。
比重超过两成,说明这一层已经足够改变任何按字数计算的指标了,包括可读性分数和关键词密度。这类靠计数得出的指标在小语种上本来就容易失真,多出来的这一层只会让它更没法看。
这两个数字还有一个更实际的用法:拿它去反推那些已经算出来的指标错了多少。假设注音占了两成,那么按字数算的所有指标都要按这个比例往回折算一遍。折算完之后,很多此前看起来莫名其妙的曲线会突然变得合理。
第三步:拿三条管道各取一次
最后一步是把关键的几条管道各走一遍。
页面上看一次,导出的数据文件里看一次,投给平台的数据源里再看一次。
三份结果贴在同一张表上,一眼就能看出哪条管道出了问题。
这张表还有一个额外好处:它把一件抽象的事变成了三行可以并排比较的字符串,跟别的部门讲的时候,一句解释都不用。把成本变成体感,永远比讲道理管用。
这张表还应该留一列写日期。三条管道各自会因为版本升级、模板改版、供应商更换而变化,而变化通常没有任何通知。留了日期,下次出问题的时候就能一眼看出是哪条管道在什么时候变过,排查范围立刻缩小到一条线上。
三条管道并排之后,还能顺手回答一个常被问到的问题:这件事到底影响多大。把三份字符串的差异算成比例,就是一个可以写进汇报里的数字,比任何定性描述都容易被接受。
一份可以照着走的注音层处理清单
先分流,再谈别的
处理顺序很重要,第一件事必须是分流。
在取文本的地方明确指定:给人看的走一条路,给程序用的走另一条。
给程序用的那条,把注音文本元素整个排除掉,只取被注音的那一串。
这件事在前端只是一行选择器的差别,在后端是一次取值方式的调整。
分流没做之前,后面所有的优化都是在错误的字符串上做的,做得越认真错得越远。
分流这一步还有一个常被跳过的前置动作:先确认现在到底有几条取值路径。多数团队报得出两条,实际跑起来往往是四五条,因为历史上不同时期的人各写过一份。没数清楚就开始改,改完总会剩下一条谁都不记得的管道还在漏。
字段级的取舍表
分流做完,把字段过一遍。
标题、元描述、替代文本、网址、结构化数据的值,这五处一律取纯净串。
正文、商品长描述、帮助文档,这三处保留完整的注音标记。
表单里的读音字段单独一列,不跟正文那一层混用。
这张表建议写进前端的组件规范里,而不是写进内容规范里,因为它是结构问题不是写作问题。
这张表还建议加一列写明由谁负责。前五处属于工程实现,后三处属于内容规范,两拨人的工作节奏完全不同。把负责人写在表上,最大的作用是避免出现那种双方都以为对方会处理的字段,这类字段是事故率最高的。
验收的时候看什么
验收要看三个数。
第一个是站内搜索里用商品名的纯净形态能不能搜到。
第二个是导出文件里随机抽二十条商品名,有没有粘连串。
第三个是结构化数据校验工具里那几个文本字段的值,肉眼过一遍。
这三个数每次上线新品类都值得重跑一次,因为新品类往往意味着新的模板,而模板是这类问题最常见的入口。母语审校那边也应该加一条对应的验收项,具体怎么把这类项目写进审校简报,小语种译文验收清单那篇有现成的写法。
这三个数还有一个共同的好处:都可以在半小时内跑完,不需要任何专门工具。正因为便宜,才有可能真的每次上线都跑一遍。验收项一旦贵到要专门排期,它在实际项目里的执行率就会迅速掉到零,这一点比它本身查得准不准更重要。
哪些事不归语言层,一句话交出去
最后划一下边界。
注音标记在各家浏览器里的显示差异、竖排时它该落在哪一侧,这些属于排版实现,归前端。
日本本地搜索引擎在这一层的具体行为差别,归引擎那一侧,跟日本本地搜索引擎的机制差别那篇合起来看更完整。
字体缺字导致注音显示不出来,属于字体子集问题,小语种网页字体的字形集成本里有完整的度量口径。
本文只管一件事:同一个位置上的两串文字,各自应该流向哪里。
这几件事交出去之后,还要留一句话给接手的人:他们各自那一层怎么做都行,唯一的硬要求是不能把两串文字合并成一串。把边界写成一句可验证的约束,比把它写成一个模糊的责任划分有用得多,接手的人也更容易照做。
常见问题解答
不做日本市场,这一篇跟我有关系吗?
有关系,但关系在方法不在语言。这套标记在中文的拼音标注、韩语的汉字括注里同样成立,只要你的页面上出现过一个位置摞两串字的情形,本文的分流思路就能直接搬。更重要的是那条判据本身:凡是给人看的东西和给程序用的东西共用同一个取值口,迟早要出事。这个道理在图片替代文本、在结构化数据、在锚文本上都成立过一次。
所以就算你的站上一个日文字都没有,把最后那份三条管道并排取值的自检表留下来也不亏。真正需要日语知识的部分,本文已经压缩到只剩一次复制粘贴。换个角度说,这一篇真正的对象不是日语,而是任何一处人机共用的取值口。真正需要日语知识的部分只剩一次复制粘贴,剩下的全是流程问题。
直接把注音全删掉,是不是最省事?
省事,但通常不允许。面向低年级儿童的商品,超出学年配当的汉字必须给读音,这是行业惯例也是家长的实际需求。姓名和地址表单里的读音字段是独立存在的,删了表单就不成立。真正可以考虑删的只有一种情况:这一层注音是模板批量加的,加得毫无道理,正文里连难字都没有。这种情况下删掉不但省事还能提可读性。
判断办法是抽二十个商品名,看被注音的汉字里有几个是常用字,如果超过八成都是常用字,那这一层大概率是模板加的,可以整层去掉。删之前记得先问一句这个决定谁能拍板。删之前还要确认一件事:这些注音是不是被别的系统当成数据源在用,比如排序或者搜索。这类决定最好由内容和法务一起拍板,工程侧只负责执行。
用回退括号那个标签,是不是就万事大吉了?
不是。回退括号只在不支持这套显示的环境里起作用,而绝大多数取文本的程序并不属于不支持的环境,它们只是根本不看显示。换句话说,回退括号解决的是显示降级,不解决取值污染。用了它之后,粘连串会变成带括号的串,比原来好读一点,但依然不是你想要的那个词。
它真正的价值是给一部分老旧环境一个体面的展示,以及提醒你这套机制天生就有两种读法。所以该写还是要写,但别指望它能替你把数据管道理顺。分流那一步一步都省不掉。另外它在无障碍那一侧也有作用,部分读屏软件会依赖这对括号决定要不要把读音念出来。把它当成一个提示信号来读,比把它当成解法有用得多。
站内搜索到底该索引哪一串?
两串都索引,但要分开索引,不能拼在一起。被注音的那一串进主字段,注音本身进一个独立的辅助字段,两者之间不做拼接。这样用户打汉字能搜到,打假名也能搜到,而且不会产生任何一个不存在的词。绝大多数搜索引擎都支持多字段检索,这不是什么高级功能。真正要避免的做法是把整段文本原样丢进索引,那样索引里全是粘连串,用户打什么都对不上。
设置完之后随手做一次验证:拿一个带注音的商品名,分别用汉字和假名各搜一次,两次都应该命中同一条。如果搜索引擎不支持多字段,退一步的办法是把注音那一串单独存成一条同义词记录,效果接近。配好之后每季度抽查一次,成本很低。
这一层会不会被判成关键词堆砌?
正常使用不会。注音的出现有明确的语言学理由,密度也受限于难字的数量,不构成异常重复。真正需要担心的是另一种做法:有人发现注音能往页面上多塞一层文字,就故意给不需要注音的常用字全都加上,甚至把注音写成关键词而不是读音。那种做法既伤可读性又确实属于操纵,风险自负。
判断自己有没有越界很简单,看被注音的字里有多少是真的需要读音的。如果一个面向成年人的页面上通篇都是注音,那已经不是语言问题了。按规矩用这一层,从来不需要担心这件事。还有一个简单的自查:看这一层的密度在各个页面之间是不是稳定,突然某一类页面高出一截就值得看看。按语言的实际需要用这一层,从来不会踩到这条线。
为什么校验工具一个警告都没报?
因为拼接产出的字符串在形式上完全合法。它由合法的汉字和合法的假名组成,编码正确,没有不可见字符,没有非法码位,长度也在范围内。所有以合法性为判据的检查器面对它都只能放行。这跟译文里加粗罩错了词是同一种处境:能自动校验的只有形式,语义那一层天然需要一个懂这门语言的人看一眼。这也是为什么这类问题的平均存活时间都以年计。
要想让机器帮你发现,唯一的办法是自己加一条针对性的规则,比如检测汉字后面是否紧跟着与之对应的假名,这条规则不难写,只是没有任何现成工具会默认带上它。这条规则最好挂在内容入库那一步,而不是挂在发布之后的巡检里,越早拦住修起来越便宜。规则本身十几行就能写完,难的是有人想到要写。
什么时候该把这件事排进日程?
三个时机。第一个是准备进日本市场之前,这时候改成本最低,因为模板还没定型。第二个是换了内容管理系统或者换了前端框架之后,取值方式很可能跟着变了。第三个是发现站内搜索命中率异常低、或者投给平台的数据源被打回的时候,这两种症状指向这里的概率相当高。除此之外不必主动排查,因为这一层稳定,规则不会自己变。
真要排一个优先级,它排在结构化数据之后、图片替代文本之前,因为它影响的是数据能不能用,而不只是能拿多少流量。已经出过一次事故的团队,一般不需要人提醒。如果三个时机都没赶上,那就等第一次导出数据被平台打回,那通常是它最后一次给你提醒。排查一次能管很久,因为这一层的规则本身不会变。
权威参考资料
本文标题:《日语页面上那行小字是给孩子读的,抽答案的程序把它当成了正文》
本文链接:https://zhangwenbao.com/minor-language-ruby-annotation-phonetic-layer.html
版权声明:本文原创,转载与引用请注明作者与原文链接。许可协议: CC BY 4.0