14.1 需要统计什么?

当我们开始思考如何统计函数定义中的单词时,第一个问题(或者说应该问的问题)是:我们要统计什么? 当我们针对 Lisp 函数定义谈论 “单词” 时,实际上大部分指的是符号。例如,下面的 multiply-by-seven 函数包含五个符号:defunmultiply-by-sevennumber*7。 此外,在文档字符串中还包含四个单词:‘Multiply’、‘NUMBER’、‘by’ 和 ‘seven’。 符号 ‘number’ 重复出现,因此该定义总共有十个单词与符号。

(defun multiply-by-seven (number)
  "Multiply NUMBER by seven."
  (* 7 number))

但如果我们用 C-M-hmark-defun)标记 multiply-by-seven 定义, 然后对其调用 count-words-example,会发现 count-words-example 声称该定义 有十一个单词,而不是十个!哪里出了问题!

问题有两方面:count-words-example 不把 ‘*’ 算作单词,并且将单个符号 multiply-by-seven 计为三个单词。连字符被当作单词间的分隔符,而非单词内部连接符: ‘multiply-by-seven’ 被当作 ‘multiply by seven’ 统计。

造成这种混淆的原因是 count-words-example 定义中用于逐个单词移动光标位置的正则表达式搜索。 在标准版本的 count-words-example 中,正则表达式为:

"\\w+\\W*"

该正则表达式定义的模式是:一个或多个单词构成字符,后接可选的一个或多个非单词构成字符。 而“单词构成字符”的含义将我们引向语法问题,这值得单独用一节讲解。