因为工作不够细致,最终版本的《精通正则表达式》还存在如下问题,只能以勘误形式发布作为补救了,请各位读者见谅。
如果大家在阅读中发现其他问题,欢迎来信指出。
yusheng.regex@gmail.com

Update:2009年2月24日,新发布了Excel版本的勘误列表,包括了之前收集的所有勘误,并给出了印次信息,更方便阅读和修改,本勘误列表不再更新,请大家下载Excel版本的勘误列表:MRE_errata.xls


 

推荐序

vi页, 第1行, “那它就被成为阳春应用”,应该修改为“那它就被称为阳春应用”;

前言

Ⅱ页,倒数第3段,“读这本书以前,我以为自己了解正则表达式,但现在我才真正了解”应修改为“读这本书以前,我以为自己了解正则表达式,但现在我才真正弄明白”

Ⅱ页,倒数第2段,“在其它任何地方都难以找到这样丰富的细节”应修改为“在其它任何地方都难以找到这样完整而详尽的资料”

Ⅴ页,第1段,“来开发引擎的能力,并避免其中的缺陷”应修改为“来发掘引擎的能力,绕开引擎的缺陷”

Ⅵ页,第1段,“[…]表示一对方括号,之间的内容无关紧要;而[…]表示一对方括号,其中包含三个句点”应修改为“[…]表示其间内容无关紧要的一对方括号,而[…]表示包含三个句点的方括号”

第1章

2页,倒数第2段,“但是它不一定能代表正则表达式在平时解决的那些“不值一提”(uninteresting)的问题。这里的“不值一提”是指这 类问题并不能成为谈 资,可是不解决它们,你就没法继续干活”应修改为“但是正则表达式在平时还用来解决那些“讨人厌(uninteresting)”的问题。说“讨人厌”, 是因为它们不适合跟外人吹嘘,可是不解决它们,你就没法继续干活”

3页,第12行,“^(From|Sbuject):”应修改为“^(From|Subject):”

6页,标题“正则表达式的思维框架”应修改为“理解正则表达式的结构”

9页,倒数第3段,“在搜索HTML代码的头文件时这非常有用”应修改为“在搜索HTML Header时这非常有用”

12页,注4中“作为一个小孩子,那时候我感觉非常受伤”应修改为“当时我还是个孩子,很伤心”

14页,第4段,“匹配一行的起始位置,然后匹配「^From」、「Subject」或「Date」中的任意一个”应修改为“匹配一行的起始位置,然后匹配「From」、「Subject」或「Date」中的任意一个”

15页,第3段,“我使用-i参数的频率很高”应修改为“我经常使用-i参数”

15页,倒数第4段,“>”字符不应该是黑体

17页,倒数第3段,“无论u是否出现,匹配都是成功的”应修改为“无论u是否出现,匹配都会成功”

18页,倒数第3段,“因为它们限定了所作用元素的匹配次数”应修改为“因为它们限定了所作用元素的重现次数”

19页,第2段,“一个字符组是一个“元素”(unit),所以它可以直接加加号、星号等,而不需要用括号”应修改为“一个字符组就是一个“元素”(unit),可以对它直接使用加号、星号等,而不需要括号”

19页,倒数第1段,“每个量词都规定了匹配成功至少需要的次数下限,以及尝试匹配的次数上限”应修改为“每个量词都规定了匹配成功至少需要的重现次数下限,以及尝试匹配的重现次数上限”

20页,表1-2中:“可以不出现,也可以只出现一次”修改为“可以出现,也可以只重现一次”;“可以出现无数次,也可以不出现”修改为“可以重现无穷多次,也可以不出现”; “可以出现无数次,但至少要出现一次”修改为“可以重现无穷多次,但至少要出现一次”

21页,倒数第2段,“这并不是正则表达式的错误”应修改为“正则表达式对此无能为力”

27 页,第1段,“而且说“如果你写一个正则”,“巧妙的正则”(budding regexers),甚至是“正则化”(regexification)”修改为“而且说“如果你写一个正则”,“巧妙的正则”(budding regexers),甚至是“正则化”(regexification)听起来更顺一些。我说的“正则引擎(regex engine)”指的是程序中实际执行匹配尝试的那个部分”

第2章

37页,第1段,“它们都非常不同于“传统”的语言,例如C和Pascal”应修改为“它们截然不同于C和Pascal之类“传统”的语言”

37页,第13行,“print “celsuius C is … #返回摄氏和华氏温度” 应修改为 “print “celsuius C is … #输出摄氏和华氏温度”

38页,倒数第1段,“运算符==用来测试两个数字是否相等”修改为“运算符==用来测试两个数值是否相等”

40 页,第1段,“我不想在本章中讨论Perl的细节,但是我告诉你用printf(“格式化输出(print formatted)”)可以解决这个问题”修改为“我不想在本章中讨论Perl的细节,不过我还是想说,printf(“格式化输出(print formatted)”)可以解决这个问题”

40页,第3段,“Perl通常情况下不区分整数和浮点数”修改为“Perl一般不区分整数和浮点数”

41页,倒数第1段,“我们发现,这个图让我们很容易地决定匹配之后应该干什么”修改为“看了这张图,我们很容易就能决定匹配之后应该干什么”

46页,补充内容的最后1段,“尽管因为第4章将会解释其原因,字符组的效率通常还是会高一点”修改为“不过根据第4章解释的原因,字符组的效率通常要高一些”

56页,倒数第2行,“^From: (\s+) \”修改为“^From: (\S+) \”(S的大小写不同)

57页,第3行,“^From: (\s+) \”修改为“^From: (\S+) \”(S的大小写不同)

67页,第3段下面,正则表达式“$text =~ s/(\d)(?=(\d\d\d)+(?!\d)/$1,/g”应修改为“$text =~ s/(\d)(?=(\d\d\d)+(?!\d))/$1,/g”,少了一个括号

70页,第2段,所以整个正则表达式的意义就不再是“寻找空行及只包含空白字符的行”,而是“寻找连续、空行和只包括空白字符的行的结合”
应修改为
所以整个正则表达式的意义就不再是“寻找空行或只包含空白字符的行”,而是“寻找空行和只包含空白字符的行的结合”

76页,倒数第2段,“此外,我们的匹配主机名的正则表达式只存在一个“主源(main source)””应修改为“此外,我们的匹配主机名的正则表达式只存在一个“源头(main source)”,”

第78页
示例2-3中第4标注
{\e[7m$1\e[m$2\e[7m$3\e[m ] igx;
应修改为
{\e[7m$1\e[m$2\e[7m$3\e[m } igx;

第3章

89页,第1段,“不支持字符组中的\w(完全不支持\d和\s)”应修改为“在字符组中无法使用\w(\d和\s在任何地方都无法使用)”

92页,倒数第2段,“在极端的情况下,反向引用的“行为”有意义吗?”应修改为“在极端的情况下,反向引用还能正常工作吗?”

93页,第12行,”┌(July|Jul)┘和┌\(July\|Jul\)┘能够取得同样的匹配结果…“应修改为”┌(Jul|July)┘和┌\(July\|Jul\)┘能够取得同样的匹配结果…“

95页,标题“函数式处理的例子”应修改为“程序式处理的例子”

95页,倒数第1段,“不过,Java也提供了一些函数式处理的……”应修改为“不过,Java也提供了一些程序式处理的……”

95页,Pattern r = Pattern.compile(“^Sujbcet:(.*)”,Pattern.CASE_INSENSITIVE);
其中的Sujbcet应写为Subject

96页,第2段,“Sun的package同时提供了程序式和面向对象式的处理方式是常见的做法”应修改为“Sun的package同时提供了程序式和面向对象式的处理方式,这是种常见的做法”

96页,倒数第六行,”出现NULL(而且可以用点号来匹配)。“应修改为”出现NUL(而且可以用点号来匹配)。“

111页,第1段,“常见的例子是大写的ß是两个字符的组合“SS”。这种情况只有Perl能够正确处理”应修改为“常见的例子是,大写的ß由两个字符“SS”组合而成。这种情况只有Perl能够正确处理”

114页,“字符组及相关结构”中,“字符组缩略表示法”应修改为“字符组简记法”

119页,第2行,”范围内的所有字符…(例如,[0-9]与[908176354]是一样的。)…“应修改为”范围内的所有字符…(例如,[0-9]与[9081763542]是一样的。)…“

130页,3-11表名“脚本语言中的行锚点”应修改为“若干语言中的行锚点”

131页,第1段,“如果结合上面那一点”应修改为“结合第一点”

132页,第3段,“但是这段程序的执行单位不是一次表达式而是一次匹配”应修改为“但是,循环的单位不是单个的表达式,而以一组表达式的匹配”

134页,“中间一级不过是“语法(syntactic sugar)”,表达方式更美观而已,”应修改为“中间一级不过是用起来更方便而已(syntactic sugar)”

第4章

152页,倒数第1段,括号内,“抑制自己的天性”应修改为“克制自己的本能”

156 页,第3段,“也就是说“不到最后关头不能分胜负(It’s not over until the fat lady sings)”,但这段话又不符合本段的语境”
应修改为
“也就是说“不到最后关头不能分胜负(It’s not over until the fat lady sings)””

156页 第3段 第2行
原文: 即使某个字表达式能够匹配
应改为:即使某个子表达式能够匹配

160页 文字部分的 第5行
原文: 字符串的b之前(也就是当前的位置)匹配
应该为:字符串的c之前(也就是当前的位置)匹配

172页,第2段,“就可以命令正则引擎不必检查它们:「^(?>\w+)」”应修改为“就可以命令正则引擎不必检查它们:「^(?>\w+):」”

172页,最后一段,最后一个正则表达式(\.\d\d[1-9]?+)^\d+,应该修改为(\.\d\d[1-9]?+)\d+

173页,第一段,第2个正则表达式(?>M)+应修改为(?>M+)。

第5章

188页 文字部分的 第4段 第2行 结尾
原文: 也不比担心
应该为:也不必担心

189页,倒数第9行,”我们也把能把匹配三位数的多选分支放在最前面,这样…”应修改为”我们就把能把匹配三位数的多选分支放在最前面,这样…”

191页,代码段中的注释大小写错误,“#利用正则表达式检测wholePath”应修改为“#利用正则表达式检测WholePath”

193页,第6行,”算式中的括号。我们…想到┌\bfoo\([^])*\)┘,但这行不通。”应修改为”算式中的括号。我们…想到┌\bfoo\([^)]*\)┘,但这行不通。”

194页,第5行,”┌\[^()]*(\([^()]*\)[^()]*)*\)┘“应修改为”┌\([^()]*(\([^()]*\)[^()]*)*\)┘”

195页,倒数第1段,“虽然这个表达式比最开始的好得多”应修改为“虽然这个表达式比开头那个好一些”

197页,第3段,“所以,我们得用别的办法来解决”应修改为“所以,得想点别的办法”

197页,第4段,“仔细想想我们想要匹配的位于开始分隔符和结束分隔符之间的文本”应修改为“仔细想想要匹配的位于开始分隔符和结束分隔符之间的文本”

197页,倒数第3段,“如果回溯会导致不期望,与多选结构有关的匹配结果”应修改为“如果回溯会导致不期望的、与多选结构有关的匹配结果”

199页,第5段,“这个正则表达式曾被用作降解忽略优先量词的绝佳例子”应修改为“这个正则表达式曾被用作讲解忽略优先量词的绝佳例子”

199页,倒数第2段,“但它并不正确(其实这三个表达式都不正确)”应修改为“但它并没有错(其实这三个表达式都没有错)”

203页,标题“检查HTTP URL”应修改为“校验HTTP URL”,目录中也应同样修改

205页,代码段注释中,“零个或多个据点分隔的部分”应修改为“零个或多个点号分隔的部分”

210页 最后一行
原文:导致逆序环视(?!44)失败
应改为:导致否定顺序环视(?!44)失败

第6章

225页,第2段,“对于没有转义字符的字符串来说,这样会一次读入整个字符串”应修改为“不包含转义字符的字符串,会被一次读入”

228页,倒数第3行,”从最后保存的状态开始回溯,在“…anise”处开始尝试…”应修改为”从最后保存的状态开始回溯,在“…anese”处开始尝试…”

233页,倒数第1段,“所以,对这个例子来说,多选结构要比字符组快22倍左右”应修改为“所以,对这个例子来说,字符组比多选结构快22倍左右”

234页,第4段,“新增的开销大约花费了5s的时间”应修改为“新增的开销大约是5秒”

234页 正文部分第2行
原文:现在,测试字符串只是上面的长度的1/1000,而测试需要进行1000次。
应该为:现在,测试字符串只是上面的长度的1/1000,而测试需要进行1000000次。

246页,第1段,“也能够减少传动装置真正应用正则表达式的位置”应修改为“也能减少传动装置真正应用正则表达式的次数”

262页,倒数第12行,”举例来说,如果目标…,那么使用的自表达式就是…“应修改为”举例来说,如果目标…,那么使用的正则表达式就是…”

265页,第12行,”┌(\{[^}]*\)| +)*┘(它永远不会终止)。或许…“应修改为”┌(\{[^}]*\}| +)*┘(它永远不会终止)。或许…”

265页,第13行,表格中的”Special”应修改为”special”

265页,第14行,“ ┌\{[^]}*\}}”应修改为” ┌\{[^}]*\}┘”

265页,第15行,“ 我们得到┌\{[^]}*\)┘*”应修改为” 我们得到┌\{[^}]*\)*”

266页,第3行,“┌ *(\{[^]}*\} *)*┘”应修改为“┌ *(\{[^}]*\} *)*┘”

266页,倒数第2行,“每次[^\\”]+的匹配终止…”应修改为“每次┌[^\\”]+┘的匹配终止…”

266页,第3段,“你就能把这几条推广开来”应修改为“就能把这几条推广开来”

266页,倒数第4段,“事实上,如果点号不能匹配换行符”应修改为“事实上,如果点号能够匹配换行符”

269页,第1段,“不会在匹配时陷入徒劳的尝试”应修改为“无法匹配时会陷入徒劳的尝试”

271页,倒数第3行,”现在处理$field…”应修改为“#现在处理$field…”

274页 上数第4行
原文:紧跟在x之后的斜线
改正:[^x]/ 是紧跟在不是x的字母后面的斜线

第7章

293页,倒数第1段,“动态作用域会临时“保护”全局变量”应修改为“动态作用域会把全局变量临时“遮蔽”起来”

296页,倒数第2段,“为方便起见,我们也可以给本地变量赋一个值 local($SomeVar),这等于把undef赋值给$SomeVar”应修改为“为方便起见,我们也可以给 local($SomeVar)赋值,这等于给$SomeVar明确赋值,而不是使用undef”

299页,第3段,“分散在散落的 local、子程序和本地变量引用之间的复杂交互”应修改为“分布在散落的 local、子程序和本地变量引用之间的复杂交互”

300页,正文第1段,“你可以期望$ 的起点是开始尝试位置的文本,但它每次都是从整个字符串的开始位置开始的”应修改为“你可能认为$ 的起点是开始尝试位置的文本,其实它每次都是从整个字符串的开始位置开始的”

301页,倒数第1段,“明确设定的$1 等变量中,闭括号在最后”应修改为“明确设定的$1 等变量中,闭括号在最后的那对括号”

308页,标题“指定目标运算元”应修改为“指定匹配目标运算元”

326页,第2段,“split 没有返回的部分或全部的文本”应修改为“通常情况下split不会返回的部分或全部的文本”

327页,标题“嵌套代码结构”应修改为“内嵌代码结构”

356页,第1段,“不包含捕获型括号的正则表达式可以不必保存拷贝”应修改为“不包含捕获型括号的正则表达式可以不必保存副本”

361页,第4段,“这很适合检查单个的正则表达式的编译方法”应修改为“这很适合检查单个正则表达式的编译过程”

第8章

365页,第5行,“sjava.util.regex一经发布就给人留下了深刻印象”应修改为“java.util.regex一经发布就给人留下了深刻印象”

367页,倒数第7行,”\0octal要求开头为0,后接1到3位十进制数字。”应修改为”\0octal要求开头为0,后接1到3位八进制数字。”

368页,表头,”表8-3:java.util.regex 中Match和Regex的方法”应修改为”表8-3:java.util.regex 中Match和Regex的模式”

368页,表8-3,“Patern.UNIX_LINES”应修改为“Pattern.UNIX_LINES”,”Pattern.CANNON_EQ”应修改为”Pattern.CANON_EQ”

368页,表8-3倒数第3行,“对Unicode字符进行不区分大小写的匹配”应修改为“对非ASCII字符进行不区分大小写的匹配”

369页,倒数第4段,“Unicode block的支持要求使用‘In’前缀”应修改为“Unicode区块的支持必须使用‘In’前缀”

371页,第2段,“就我个人来说,更喜欢简称前两个为“pattern”和“matcher””应修改为“我自己更喜欢把前两者简称为“pattern”和“matcher””

371页,第16行,”IllegalAgumentException”应修改为“IllegalArgumentException”

371页,倒数第4行,”结果是‘matched [1st] from 12 to 15.’。在本章的所有例子…”应修改为“结果是‘matched [1st] from 11 to 14.’。在本章的所有例子…”

373页,第1行,“调用Patern.compile可能抛出两种类型的异常:如果…”应修改为“调用Pattern.compile可能抛出两种类型的异常:如果…”

374页,第13行,”…和hasTran-sparentBounds方法来修改和查询…”应修改为”…和hasTransparentBounds方法来修改和查询…”

374页,倒数第6段,“当前pattern的捕获型括号的数目”应修改为“当前pattern中捕获型括号的数目”

377页 倒数第7行
原文:int end()
次方法返回整个匹配的终点的绝对偏移值
改为:此方法返回整个匹配的终点的绝对偏移值

377页,函数“String gropu(int num)”应修改为“String group(int num)”

377页,倒数第5行,“MatcheResult toMatchResult()”应修改为“MatchResult toMatchResult()”

377页,倒数第2行,“如果前一次匹配不成功,或者…调用 toMatcheResult”应修改为“如果前一次匹配不成功,或者…调用 toMatchResult”

378页,第5行
String regex = “(?x) ^(https?):// ([^/:]+) (?:(\\ d+))?”;
应修改为
String regex = “(?x) ^(https?):// ([^/:]+) (?::(\\ d+))?”;

378页倒数第3行,“string.replaceAll(regex,replacement)”应修改为“String.replaceAll(regex,replacement)”

388页,最后一段,“即检索范围不等于整个目标字符串”应修改为“即使检索范围不等于整个目标字符串也是如此”

389页,标题“构建扫描程序”应修改为“构建扫描程序的方法”

401页,倒数第6行,”不断创建-回收 Mather”应修改为“不断创建-回收 Matcher”

第9章

410页,第5段,“即用即编译(On-The-Fly Compilation)”应修改为“直接编译(On-The-Fly Compilation)”

410页,倒数第2段,“来进行“即用即编译”的编译”应修改为“来进行“直接编译”的编译”

432页,标题“支持函数”应修改为“辅助函数”

432页,倒数第4段,“还有一些静态的支持函数”应修改为“还有一些静态辅助函数”

438页,倒数第3段,“尽管涌出并不大”应修改为“尽管用处并不大”

第10章

442页,第3段,“十进制转义只能接受两到三位八位数值”应修改为“八进制转义只能接受两到三位八进制数字”

445页,倒数第5段,“第448也给出了一个“不好”的原因”应修改为“第448页给出了一个“不好”的理由”

455页,第3段,“这就是默认的配列方式”应修改为“这就是默认的排列方式”

459页,第3段,“这个简单的例子把HTML中的bold tag全部转换为大写”应修改为“这个简单的例子在HTML中的所有大写单词两端加上bold tag”

459页,倒数第4段,“下面这个扩展的例子把bold tag里的单词变为小写”应修改为“下面这个扩展的例子在添加bold tag的同时把单词转换为小写”

460页的表格,第三行开头应该为“数组 数组”,第四行开头应该为“字符串 数组”