那个不存在的单词「an unicorn」,和 129 个例外
目录
- 一个成年人才会注意到的英语问题
- 32455 个词,129 个例外
- y 和 w:被开除出元音队伍的叛徒
- h 的失踪案:从 heir 到 honor
- The Letter Name Trap:26 个字母自己也要选 a/an
- an apron 的诞生:一场流传几百年的耳朵误会
- 现场验证:我把发音词典整本翻了一遍
- 一个循环,和一套手写规则
一个成年人才会注意到的英语问题
英语里有个规则,小学老师教的:a 用在辅音开头的词前面,an 用在元音开头的词前面。a cat、an apple。就这么简单。
然后你遇到了 unicorn。
unicorn 以元音字母 u 开头,按规则应该是 an unicorn——但没有任何一个母语者会说 an unicorn。我们都说 a unicorn,因为 unicorn 虽然写起来是元音开头,读起来却是辅音开头:/junɪkɔrn/。u 在单词里读成了 "yoo",y 是辅音音。
所以真正的规则不是「看第一个字母」,而是「听第一个音」。
问题是:这个「听音」的规则,到底有多准?用「看字母」的规则去碰运气,会错多少次?Red Blob Games 的作者 Amit Patel 花了整整一天去查发音词典,最后发现:32455 个英文单词里,只有 129 个是例外。
129 个,一张纸就能列完。这是整篇故事里最让我意外的数字——我以为会错一大片,结果差点就是 0。
32455 个词,129 个例外
Amit 干了一件程序员才会干的事:把卡内基梅隆大学的发音词典(cmudict)整本下载下来,然后写代码判断「第一个字母是元音吗」和「第一个音是元音吗」是否一致。
结果出乎意料地好。**32455 个单词(排除了专有名词、单字母、缩写、标点后),按「首字母规则」判断,只有 129 个词会翻车。**准确率 99.6%。
这 129 个例外不是随机散布的,它们整整齐齐地聚成了几个家族:
| 家族 | 代表词 | 为什么例外 |
|---|---|---|
eu- 读成 /ju/ |
eucalyptus, eunuch, eulogy | e 开头但读 yoo |
u- 读成 /ju/ |
unicorn, university, urology | u 开头但读 yoo |
h- 不发音 |
hour, heir, honest, honor | h 开头但元音开头 |
o- 读成 /w/ |
one, once, oneness | o 开头但读 wuh |
看到规律了吗?大半的例外都是同一个音在捣乱:/j/。
eucalyptus 和 unicorn 表面差很远,但开头都是那个「yoo」音——一个由字母 y 或 u 假装发出来的辅音。英语把 /j/ 归为辅音,于是所有以 yoo 开头的词,哪怕写作 e 或 u,都得用 a。
y 和 w:被开除出元音队伍的叛徒
英语的元音字母五个:a, e, i, o, u。但发音上真正在「元音/辅音」之间摇摆的,是 y 和 w。
y 在 yes、yard 里是辅音,在 myth、gym 里是元音。w 在 water 里是辅音……可 one、once 开头的音其实就是 /w/,所以它们写作 o 开头,却读作 w 开头——于是 one 按首字母规则会被判成 an one,大错特错。
最讽刺的例子是 yttrium(钇,化学元素)。它是 129 个例外里唯一一个不属于任何家族的孤儿:以辅音字母 y 开头,却读作 /ˈɪtriəm/,是元音开头,所以它要 an yttrium。一个辅音字母,读出了元音,独自一人站在例外列表的角落。
英语拼写和发音之间的裂缝,在这个单词上裂到了最大。
h 的失踪案:从 heir 到 honor
另一大族是「h 不发音」。
hour 的 h 不发音,所以是 an hour;heir、honest、honor、honorary、honorific 全都一样,h 是哑巴,元音是首领。herb 在美国英语里 h 也不发音(an herb),但在英国英语里 h 发音(a herb)——同一个词,两个国家,两种 a/an。
Amit 的规则代码里有个有趣的注释:他没处理古老的 an hospital 例外。很久以前,英语有些方言不发音 h,所以人们说 an hospital,这个用法写进了书和报纸。后来发音变化,h 恢复了声音,an hospital 就变成了一条例外中的例外——正在慢慢消亡。语言是活的,规则列表会过期。
The Letter Name Trap:26 个字母自己也要选 a/an
最让我会心一笑的,是 Amit 提到的第二个场景:单个字母的名词,也要选 a/an。
你要是念一个密码 FBI,你会说 an FBI agent 还是 a FBI agent?答案是 an,因为 F 这个字母的名字读作 /ɛf/,是元音开头。而 NASA 读作 /ˈnæsə/,辅音开头,所以要 a NASA mission。
我把 26 个字母按它们自己的发音过了一遍,得出:
用 an 的 12 个:A, E, F, H, I, L, M, N, O, R, S, X
用 a 的 14 个:B, C, D, G, J, K, P, Q, T, U, V, W, Y, Z
h 读作「aitch」元音开头所以是 an H,u 读作「you」辅音开头所以是 a U——读「you」,然后发现这个字母本身又是那个 /j/ 叛徒在捣乱。整个系统,处处都是同一个幽灵。
an apron 的诞生:一场流传几百年的耳朵误会
129 个例外是「现在」的规则清单。但英语的历史里,有个更妙的机制在反向运作:重分析(rebracketing)。
维基百科的经典例子:15 世纪的人说 a napron(围裙)。因为 napron 以辅音 n 开头,所以前面是 a。但这个词太常被听见了,人们把 a napron 听成了 an apron——反正都差不多——然后干脆把那个 n 从围裙上撕了下来,安到了冠词上。几代人之后,apron 变成了标准拼写,napron 反而消失了。
同样的故事还发生在 a newt(蝾螈,来自 an ewt)、an adder(蝰蛇,来自 a nadder)、an orange(橙子,西班牙语里还叫 naranja,保留了那个 n)身上。
换句话说:今天我们在背的 129 个例外,有一部分是几百年前「an 和 a 边界上的幻觉」留下来的化石。 单词的拼写被错误切分重塑,冠词的那个 n 像个流浪汉一样,从这个词搬到那个词。你现在看到 an apron,其实是听到的 a napron。
现场验证:我把发音词典整本翻了一遍
说这么多,不如自己动手。我下载了同一份 cmudict 发音词典,把 Amit 的算法重写了一遍,然后亲自踩了他踩过的所有坑。
第一坑:cmudict 的元音音标带数字标号。 AA1 是元音,但 AA 也是。我第一版代码只检查了 ph[0] 是否在元音表里,结果把所有带重音数字的元音全部误判成辅音——跑出来「谜之 558 个例外」。和第二坑正好是同一堵墙的两面。
第二坑:全量词典 vs 过滤后的词典。 我用完整 cmudict 跑首字母规则,得到 17395 个「不匹配」——看起来天塌了。但实际上绝大多数是专有名词(fbi、html、herbert、nvidia)和缩写,它们本来就不属于「普通英文单词」。Amit 用 BSD 词典交集过滤后,不匹配立刻缩到 275 个。
第三坑:他的 129 个例外,我逐个对了一遍。 我把 Amit 文章里列的那 129 个词,全部拿去和我的 cmudict 比对——每一个都确实是「字母元音 ≠ 读音元音」的真例外。一个不多,一个不少。113 个在我的词典交集里找到了,全部验证通过。
第四验证:他的手写规则有多准? 我把 Amit 那 20 行 starts_with_vowel 手写规则原样实现,跑在我过滤后的词典上,剩下 83 个词还是错的——但看列表,全是 fbi、mit、unesco、nvidia 这类缩写/专名/外来词,正是他主动排除的类别。他的规则在他定义的范围内是完美的。
整个验证链条走完,我得出一个确定的结论:英语的 a/an 规则,99.6% 的时候「看字母」就够用;但那 0.4% 的例外,是英语拼写和发音三百年恩怨的缩影。
一个循环,和一套手写规则
最后说一个让我愣了几秒的细节。
Amit 把 129 个例外写成了 20 行硬编码的手写规则:if word.startswith("eu"): return False、if word.startswith("hour"): return True……他承认没能找到比「手写 if-else」更优雅的算法,尽管他试过把问题规约为 DFA 最小化——一个计算机科学里已经研究了 60 年的问题。
所以这是整件事最妙的闭环:英语的 a/an 选择,本质上是一个「有限状态机最小化」问题;而人类已经用自然语言把它优化了几百年。 计算机科学家想用 DFA 最小化算法来解决它,最后发现最实用的解是 20 行人类手写的规则——这 20 行规则,就是几百万英语母语者脑子里那套「听起来顺不顺」的近似实现。
规则可以写进代码,但规则的来历(为什么要为 hour 破例?为什么 yttrium 是孤儿?)只能靠历史来讲。a/an 这个小到不能再小的英语功能词,底下埋着一整部音韵学、词源学和拼写改革的历史。下次你犹豫要不要说 an unicorn 的时候,记住:你是在和一个 300 年的语言系统搏斗,而它已经赢了。
评论(0)
暂无评论,来写第一条吧~