<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>李卫公的长安城</title><link>http://blog.donews.com/maverick/</link><description>过上一万年，那城就会变成黑色，永远不倒……</description><dc:language>zh-CHS</dc:language><generator>.Text Version 1.0.1.0</generator><item><dc:creator>李卫公</dc:creator><title>五一节掠影</title><link>http://blog.donews.com/maverick/archive/2008/05/02/1285450.aspx</link><pubDate>Fri, 02 May 2008 11:06:00 GMT</pubDate><guid>http://blog.donews.com/maverick/archive/2008/05/02/1285450.aspx</guid><wfw:comment>http://blog.donews.com/maverick/comments/1285450.aspx</wfw:comment><comments>http://blog.donews.com/maverick/archive/2008/05/02/1285450.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blog.donews.com/maverick/comments/commentRss/1285450.aspx</wfw:commentRss><trackback:ping>http://tb.donews.net/TrackBack.aspx?PostId=1285450</trackback:ping><description>&lt;img src="http://www.luanxiang.org/blog/wp-content/uploads/2008/05/amazon.jpg" alt="" /&gt;&lt;img src ="http://blog.donews.com/maverick/aggbug/1285450.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>李卫公</dc:creator><title>技之所在，艺之所倚</title><link>http://blog.donews.com/maverick/archive/2008/04/07/1274255.aspx</link><pubDate>Mon, 07 Apr 2008 14:44:00 GMT</pubDate><guid>http://blog.donews.com/maverick/archive/2008/04/07/1274255.aspx</guid><wfw:comment>http://blog.donews.com/maverick/comments/1274255.aspx</wfw:comment><comments>http://blog.donews.com/maverick/archive/2008/04/07/1274255.aspx#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://blog.donews.com/maverick/comments/commentRss/1274255.aspx</wfw:commentRss><trackback:ping>http://tb.donews.net/TrackBack.aspx?PostId=1274255</trackback:ping><description>数据库？不就是MySQL之类嘛！
关系？不就是表嘛！
数据库设计？对着界面就能想出来嘛！
考虑不周全？改表嘛！
速度不够快？你建索引了吗？加索引嘛！
……
在我的开发经验中，类似的问答并不罕见。可是，这正常吗？&lt;img src ="http://blog.donews.com/maverick/aggbug/1274255.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>李卫公</dc:creator><title>解决Gmail连接被阻断的问题</title><link>http://blog.donews.com/maverick/archive/2007/12/14/1236608.aspx</link><pubDate>Fri, 14 Dec 2007 09:32:00 GMT</pubDate><guid>http://blog.donews.com/maverick/archive/2007/12/14/1236608.aspx</guid><wfw:comment>http://blog.donews.com/maverick/comments/1236608.aspx</wfw:comment><comments>http://blog.donews.com/maverick/archive/2007/12/14/1236608.aspx#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://blog.donews.com/maverick/comments/commentRss/1236608.aspx</wfw:commentRss><trackback:ping>http://tb.donews.net/TrackBack.aspx?PostId=1236608</trackback:ping><description>&lt;p&gt;在用浏览器访问Gmail时，经常会遇到这样的情况，登录成功，但马上便提示无法连接服务器，这其实是因为Gmail的Web页面默认启用的聊天功能被GFW所致，解决的办法就是关掉Web中的聊天功能，具体设置如。&lt;/p&gt;
&lt;p&gt;下面的截图是登录Gmail之后，在浏览器最下边显示的信息。在默认情况下，用户的选项是最左边的&amp;ldquo;standard with chat&amp;rdquo;，我们登录Gmail之后，抢在连接被阻断之前，选择&amp;ldquo;standard without chat&amp;rdquo;，就可以了。&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.luanxiang.org/blog/wp-content/uploads/2007/12/gmail_firefox.JPG" alt="" /&gt;&lt;/p&gt;&lt;img src ="http://blog.donews.com/maverick/aggbug/1236608.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>李卫公</dc:creator><title>开发经验谈：正则表达式与字符串</title><link>http://blog.donews.com/maverick/archive/2007/10/18/1220416.aspx</link><pubDate>Thu, 18 Oct 2007 12:33:00 GMT</pubDate><guid>http://blog.donews.com/maverick/archive/2007/10/18/1220416.aspx</guid><wfw:comment>http://blog.donews.com/maverick/comments/1220416.aspx</wfw:comment><comments>http://blog.donews.com/maverick/archive/2007/10/18/1220416.aspx#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://blog.donews.com/maverick/comments/commentRss/1220416.aspx</wfw:commentRss><trackback:ping>http://tb.donews.net/TrackBack.aspx?PostId=1220416</trackback:ping><description>(欢迎转载，转载请注明出处)&lt;br /&gt;&lt;br /&gt;在日常应用正则表达式时，经常遇到的一类问题是，弄不清楚到底该如何转义&amp;mdash;&amp;mdash;最明显的表现就是，搞不懂究竟要使用多少个反斜线，大部分时候，只好盲目尝试，直到测试成功为止。但是，许多时候，这样的方法并不能完整解决问题。&lt;br /&gt;为了彻底解决这类问题，我们需要弄清楚正则表达式与字符串的关系：它其实很简单，根据我的经验，我们只需要牢记下面两条原则：&lt;br /&gt;&lt;br /&gt;1.正则表达式不等于字符串，但必须以字符串的形式给出&lt;br /&gt;&lt;br /&gt;大多数语言中都存在正则表达式（regex）对象，譬如Java语言中的Pattern对象，即使没有提供专门的对象，也需要用某些特殊的字符来标注正则表达式，譬如PHP中常用的反斜线&amp;lsquo;/&amp;rsquo;。另一方面，正则表达式对某些字符或字符序列有自己的规定，不同于字符串的规定，譬如&amp;lsquo;\b&amp;rsquo;在正则表达式中表示单词分界符，而在普通字符串中表示退格字符。因此我们可以说，正则表达式并不等于普通的字符串。&lt;br /&gt;但是，正则表达式又终究是一种处理文本的语言，因此，我们写出的所有正则表达式，都是以字符串形式提供的。&lt;br /&gt;所以，在应用正则表达式的过程中，需要进行从字符串到正则表达式本身的转换。&lt;br /&gt;也就是&lt;br /&gt;&amp;ldquo;源代码中的字符序列&amp;rdquo;-&amp;gt;&amp;ldquo;字符串&amp;rdquo;-&amp;gt;&amp;ldquo;正则表达式&amp;rdquo;&lt;br /&gt;&lt;br /&gt;譬如，在Java语言中，正则表达式中的&amp;lsquo;\b&amp;rsquo;，在以字符串表示时，必须写做&lt;br /&gt;String regex = &amp;quot;\\b&amp;quot;;&lt;br /&gt;其中第1个反斜线用来转义第2个反斜线，这样，正则表达式接受到的才是真正的&amp;lsquo;\b&amp;rsquo;，对应正则表达式中的单词分界符，如果我们写&lt;br /&gt;String regex = &amp;quot;\b&amp;quot;;&lt;br /&gt;编译也没有问题，但此时正则表达式接受的是一个字符，即退格符。&lt;br /&gt;&lt;br /&gt;需要注意的是，在Java和C#之类的语言中，如果字符串中出现的字符序列无法识别，编译会出错，譬如这样：&lt;br /&gt;String regex = &amp;quot;\w&amp;quot;;&lt;br /&gt;编译无法通过，因为根据字符串的规定，&amp;lsquo;\w&amp;rsquo;不是一个合法的转义序列，在字符串这一关就卡住了。&lt;br /&gt;&lt;br /&gt;但是在PHP和Python之类的语言中，这样写却没有问题。原因在于，如果PHP和Python发现字符串中有无法识别的转义序列，会原封不动地保存下来，这样，正则表达式接受到的，仍然是&amp;lsquo;\w&amp;rsquo;。&lt;br /&gt;当然，我们也可以在这些语言中使用&amp;lsquo;\\w&amp;rsquo;，结果是一样的，因为此时，在进行字符串处理时，第1个反斜线转义了第2个反斜线，正则表达式接受到的，仍然是&amp;lsquo;\w&amp;rsquo;。&lt;br /&gt;&lt;br /&gt;这是在实际开发中非常迷惑人的一点，只要我们弄清了正则表达式和字符串的关系，就不会再感到迷惑。&lt;br /&gt;&lt;br /&gt;2.正则表达式中单独出现的反斜线也需要转义&lt;br /&gt;&lt;br /&gt;在正则表达式中，反斜线通常与其它字符一起构成特殊的结构，譬如&amp;lsquo;\d&amp;rsquo;用来匹配数字字符，&amp;lsquo;\s&amp;rsquo;用来匹配空白字符，&amp;lsquo;\1&amp;rsquo;用来反向引用第一个分组捕获的文本。&lt;br /&gt;可是，如果我们在正则表达式中，仅仅需要表示&amp;ldquo;反斜线&amp;rdquo;字符本身，该如何做呢？&lt;br /&gt;其实，正则表达式对这个问题的处理，与字符串的处理是一样的，也就是说，在正则表达式中，必须用转义序列&amp;lsquo;\\&amp;rsquo;来表示单个反斜线。&lt;br /&gt;这个规定会带来一个有趣的问题：正则表达式中单独出现的反斜线字符，在正则表达式的层面，必须以转义序列&amp;lsquo;\\&amp;rsquo;来表示，然而，每个反斜线，在表示正则表达式的字符串中，又必须以转义序列&amp;lsquo;\\&amp;rsquo;来表示。所以，在字符串中，必须写出四个反斜线&amp;lsquo;\\\\&amp;rsquo;，才能对应到正则表达式中单独出现的一个反斜线字符：在字符串处理层面，它们会被识别为两个反斜线&amp;lsquo;\\&amp;rsquo;，在正则表达式的层面，它们会被识别为单个反斜线字符&amp;lsquo;\&amp;rsquo;。&lt;br /&gt;&lt;br /&gt;很麻烦，很困惑，但是，其实也不难明白，对吗？&lt;img src ="http://blog.donews.com/maverick/aggbug/1220416.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>李卫公</dc:creator><title>开发笔记：MySQL的维护语句</title><link>http://blog.donews.com/maverick/archive/2007/09/28/1214300.aspx</link><pubDate>Fri, 28 Sep 2007 13:51:00 GMT</pubDate><guid>http://blog.donews.com/maverick/archive/2007/09/28/1214300.aspx</guid><wfw:comment>http://blog.donews.com/maverick/comments/1214300.aspx</wfw:comment><comments>http://blog.donews.com/maverick/archive/2007/09/28/1214300.aspx#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://blog.donews.com/maverick/comments/commentRss/1214300.aspx</wfw:commentRss><trackback:ping>http://tb.donews.net/TrackBack.aspx?PostId=1214300</trackback:ping><description>&lt;span style="color: rgb(255, 0, 0); font-weight: bold;"&gt;Analyze Table&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;MySQL的Optimizer（优化元件）在优化SQL语句时，首先需要收集一些相关信息，其中就包括表的cardinality（可以翻译为&amp;ldquo;散列程度&amp;rdquo;），它表示某个索引对应的列包含多少个不同的值&amp;mdash;&amp;mdash;如果cardinality大大少于数据的实际散列程度，那么索引就基本失效了。&lt;br /&gt;我们可以使用SHOW INDEX语句来查看索引的散列程度：&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;SHOW INDEX FROM PLAYERS;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;TABLE&amp;nbsp;&amp;nbsp; KEY_NAME COLUMN_NAME CARDINALITY&lt;br /&gt;------- -------- ----------- -----------&lt;br /&gt;PLAYERS PRIMARY&amp;nbsp; PLAYERNO&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 14&lt;br /&gt;&lt;br /&gt;因为此时PLAYER表中不同的PLAYERNO数量远远多于14，索引基本失效。&lt;br /&gt;下面我们通过Analyze Table语句来修复索引：&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;ANALYZE TABLE PLAYERS;&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;SHOW INDEX FROM PLAYERS;&lt;/span&gt;&lt;br /&gt;结果是：&lt;br /&gt;TABLE&amp;nbsp;&amp;nbsp; KEY_NAME COLUMN_NAME CARDINALITY&lt;br /&gt;------- -------- ----------- -----------&lt;br /&gt;PLAYERS PRIMARY&amp;nbsp; PLAYERNO&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1000&lt;br /&gt;&lt;br /&gt;此时索引已经修复，查询效率大大提高。&lt;br /&gt;&lt;br /&gt;需要注意的是，如果开启了binlog，那么Analyze Table的结果也会写入binlog，我们可以在analyze和table之间添加关键字local取消写入。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;Checksum Table&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;数据在传输时，可能会发生变化，也有可能因为其它原因损坏，为了保证数据的一致，我们可以计算checksum（校验值）。&lt;br /&gt;使用MyISAM引擎的表会把checksum存储起来，称为live checksum，当数据发生变化时，checksum会相应变化。&lt;br /&gt;在执行Checksum Table时，可以在最后指定选项qiuck或是extended；qiuck表示返回存储的checksum值，而extended会重新计算checksum，如果没有指定选项，则默认使用extended。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;Optimize Table&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;经常更新数据的磁盘需要整理碎片，数据库也是这样，Optimize Table语句对MyISAM和InnoDB类型的表都有效。&lt;br /&gt;如果表经常更新，就应当定期运行Optimize Table语句，保证效率。&lt;br /&gt;与Analyze Table一样，Optimize Table也可以使用local来取消写入binlog。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;Check Table&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;数据库经常可能遇到错误，譬如数据写入磁盘时发生错误，或是索引没有同步更新，或是数据库未关闭MySQL就停止了。&lt;br /&gt;遇到这些情况，数据就可能发生错误：&lt;br /&gt;Incorrect key file for table: ' '. Try to repair it.&lt;br /&gt;此时，我们可以使用Check Table语句来检查表及其对应的索引。&lt;br /&gt;譬如我们运行&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;CHECK TABLE PLAYERS;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;结果是&lt;br /&gt;TABLE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; OP&amp;nbsp;&amp;nbsp;&amp;nbsp; MSG_TYPE MSG_TEXT&lt;br /&gt;-------------- ----- -------- --------&lt;br /&gt;TENNIS.PLAYERS check status&amp;nbsp;&amp;nbsp; OK&lt;br /&gt;&lt;br /&gt;MySQL会保存表最近一次检查的时间，每次运行check table都会存储这些信息：&lt;br /&gt;&lt;br /&gt;执行&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;SELECT&amp;nbsp;&amp;nbsp;&amp;nbsp; TABLE_NAME, CHECK_TIME&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;FROM&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; INFORMATION_SCHEMA.TABLES&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;WHERE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TABLE_NAME = 'PLAYERS'&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;AND&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TABLE_SCHEMA = 'TENNIS';&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;结果是&lt;br /&gt;&lt;br /&gt;TABLE_NAME&amp;nbsp;&amp;nbsp; CHECK_TIME&lt;br /&gt;----------&amp;nbsp;&amp;nbsp; -------------------&lt;br /&gt;PLAYERS&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2006-08-21 16:44:25&lt;br /&gt;&lt;br /&gt;Check Table还可以指定其它选项：&lt;br /&gt;UPGRADE：用来测试在更早版本的MySQL中建立的表是否与当前版本兼容。&lt;br /&gt;QUICK：速度最快的选项，在检查各列的数据时，不会检查链接（link）的正确与否，如果没有遇到什么问题，可以使用这个选项。&lt;br /&gt;FAST：只检查表是否正常关闭，如果在系统掉电之后没有遇到严重问题，可以使用这个选项。&lt;br /&gt;CHANGED：只检查上次检查时间之后更新的数据。&lt;br /&gt;MEDIUM：默认的选项，会检查索引文件和数据文件之间的链接正确性。&lt;br /&gt;EXTENDED：最慢的选项，会进行全面的检查。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;Repair Table&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;用于修复表，只对MyISAM和ARCHIVE类型的表有效。&lt;br /&gt;这条语句同样可以指定选项：&lt;br /&gt;QUICK：最快的选项，只修复索引树。&lt;br /&gt;EXTENDED：最慢的选项，需要逐行重建索引。&lt;br /&gt;USE_FRM：只有当MYI文件丢失时才使用这个选项，全面重建整个索引。&lt;br /&gt;&lt;br /&gt;与Analyze Table一样，Repair Table也可以使用local来取消写入binlog。&lt;img src ="http://blog.donews.com/maverick/aggbug/1214300.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>李卫公</dc:creator><title>老大哥啊老大哥</title><link>http://blog.donews.com/maverick/archive/2007/09/26/1213592.aspx</link><pubDate>Wed, 26 Sep 2007 11:49:00 GMT</pubDate><guid>http://blog.donews.com/maverick/archive/2007/09/26/1213592.aspx</guid><wfw:comment>http://blog.donews.com/maverick/comments/1213592.aspx</wfw:comment><comments>http://blog.donews.com/maverick/archive/2007/09/26/1213592.aspx#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://blog.donews.com/maverick/comments/commentRss/1213592.aspx</wfw:commentRss><trackback:ping>http://tb.donews.net/TrackBack.aspx?PostId=1213592</trackback:ping><description>&lt;p&gt;当年，斯大林同志对高尔基同志的《姑娘与死神》的批示，曾引起两名教授在《真理报》上撰文论证：斯大林同志之所以少写一个字母，是因为新生阶级的爱情截然不同于腐朽没落的资产阶级爱情。最后领袖再次批示：笨蛋，此系笔误。&lt;/p&gt;
&lt;p&gt;最近，贾平凹老师又为铁凝老师的题词张罗了一次诠释。我们的表现，确实还远远比不上当年的老大哥。&lt;/p&gt;
&lt;p&gt;奥威尔的《1984》，最后一句话是：他战胜了他自己，他热爱老大哥！看来，我们的某些同志，确实还无法战胜自己，离老大哥还差的远呢。&lt;/p&gt;&lt;img src ="http://blog.donews.com/maverick/aggbug/1213592.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>李卫公</dc:creator><title>《精通正则表达式》勘误</title><link>http://blog.donews.com/maverick/archive/2007/09/14/1209937.aspx</link><pubDate>Fri, 14 Sep 2007 11:01:00 GMT</pubDate><guid>http://blog.donews.com/maverick/archive/2007/09/14/1209937.aspx</guid><wfw:comment>http://blog.donews.com/maverick/comments/1209937.aspx</wfw:comment><comments>http://blog.donews.com/maverick/archive/2007/09/14/1209937.aspx#Feedback</comments><slash:comments>17</slash:comments><wfw:commentRss>http://blog.donews.com/maverick/comments/commentRss/1209937.aspx</wfw:commentRss><trackback:ping>http://tb.donews.net/TrackBack.aspx?PostId=1209937</trackback:ping><description>&lt;p&gt;因为工作不够细致，最终版本的《精通正则表达式》还存在如下问题，只能以勘误形式发布作为补救了，请各位读者见谅。&lt;br /&gt; 如果大家在阅读中发现其他问题，欢迎来信指出。&lt;br /&gt; yusheng.regex@gmail.com&lt;/p&gt;
&lt;hr style="width: 100%; height: 2px;" /&gt;&lt;a href="http://www.china-pub.com/computers/common/info.asp?id=35269"&gt;&lt;img alt="" src="http://images.china-pub.com/ebook35001-40000/35269/zcover.jpg" /&gt;&lt;/a&gt;
&lt;p&gt;推荐序&lt;/p&gt;
&lt;p&gt;vi页， 第1行， &amp;ldquo;那它就被成为阳春应用&amp;rdquo;，应该修改为&amp;ldquo;那它就被称为阳春应用&amp;rdquo;；&lt;/p&gt;
&lt;p&gt;前言&lt;/p&gt;
&lt;p&gt;Ⅱ页，倒数第3段，&amp;ldquo;读这本书以前，我以为自己了解正则表达式，但现在我才真正了解&amp;rdquo;应修改为&amp;ldquo;读这本书以前，我以为自己了解正则表达式，但现在我才真正弄明白&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Ⅱ页，倒数第2段，&amp;ldquo;在其它任何地方都难以找到这样丰富的细节&amp;rdquo;应修改为&amp;ldquo;在其它任何地方都难以找到这样完整而详尽的资料&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Ⅴ页，第1段，&amp;ldquo;来开发引擎的能力，并避免其中的缺陷&amp;rdquo;应修改为&amp;ldquo;来发掘引擎的能力，绕开引擎的缺陷&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Ⅵ页，第1段，&amp;ldquo;[&amp;hellip;]表示一对方括号，之间的内容无关紧要；而[&amp;hellip;]表示一对方括号，其中包含三个句点&amp;rdquo;应修改为&amp;ldquo;[&amp;hellip;]表示其间内容无关紧要的一对方括号，而[&amp;hellip;]表示包含三个句点的方括号&amp;rdquo;&lt;/p&gt;
&lt;p&gt;第1章&lt;/p&gt;
&lt;p&gt;2 页，倒数第2段，&amp;ldquo;但是它不一定能代表正则表达式在平时解决的那些&amp;ldquo;不值一提&amp;rdquo;（uninteresting）的问题。这里的&amp;ldquo;不值一提&amp;rdquo;是指这类问题并不能成为谈 资，可是不解决它们，你就没法继续干活&amp;rdquo;应修改为&amp;ldquo;但是正则表达式在平时还用来解决那些&amp;ldquo;讨人厌（uninteresting）&amp;rdquo;的问题。说&amp;ldquo;讨人厌&amp;rdquo;， 是因为它们不适合跟外人吹嘘，可是不解决它们，你就没法继续干活&amp;rdquo;&lt;br /&gt; &lt;br style="color: rgb(255, 0, 0);" /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;6页，标题&amp;ldquo;正则表达式的思维框架&amp;rdquo;应修改为&amp;ldquo;理解正则表达式的结构&amp;rdquo;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;9页，倒数第3段，&amp;ldquo;在搜索HTML代码的头文件时这非常有用&amp;rdquo;应修改为&amp;ldquo;在搜索HTML Header时这非常有用&amp;rdquo;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;12页，注4中&amp;ldquo;作为一个小孩子，那时候我感觉非常受伤&amp;rdquo;应修改为&amp;ldquo;当时我还是个孩子，很受伤&amp;rdquo;&lt;span style="color: rgb(255, 0, 0);"&gt;&lt;/span&gt;&lt;br style="color: rgb(255, 0, 0);" /&gt;&lt;br style="color: rgb(255, 0, 0);" /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;14页，第4段，&amp;ldquo;匹配一行的起始位置，然后匹配「^From」、「Subject」或「Date」中的任意一个&amp;rdquo;应修改为&amp;ldquo;匹配一行的起始位置，然后匹配「From」、「Subject」或「Date」中的任意一个&amp;rdquo;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;15页，第3段，&amp;ldquo;我使用-i参数的频率很高&amp;rdquo;应修改为&amp;ldquo;我经常使用-i参数&amp;rdquo;&lt;/p&gt;
&lt;p&gt;15页，倒数第4段，&amp;ldquo;&amp;gt;&amp;rdquo;字符不应该是黑体&lt;/p&gt;
&lt;p&gt;17页，倒数第3段，&amp;ldquo;无论u是否出现，匹配都是成功的&amp;rdquo;应修改为&amp;ldquo;无论u是否出现，匹配都会成功&amp;rdquo;&lt;/p&gt;
&lt;p&gt;18页，倒数第3段，&amp;ldquo;因为它们限定了所作用元素的匹配次数&amp;rdquo;应修改为&amp;ldquo;因为它们限定了所作用元素的重现次数&amp;rdquo;&lt;/p&gt;
&lt;p&gt;19页，第2段，&amp;ldquo;一个字符组是一个&amp;ldquo;元素&amp;rdquo;（unit），所以它可以直接加加号、星号等，而不需要用括号&amp;rdquo;应修改为&amp;ldquo;一个字符组就是一个&amp;ldquo;元素&amp;rdquo;（unit），可以对它直接使用加号、星号等，而不需要括号&amp;rdquo;&lt;/p&gt;
&lt;p&gt;19页，倒数第1段，&amp;ldquo;每个量词都规定了匹配成功至少需要的次数下限，以及尝试匹配的次数上限&amp;rdquo;应修改为&amp;ldquo;每个量词都规定了匹配成功至少需要的重现次数下限，以及尝试匹配的重现次数上限&amp;rdquo;&lt;br /&gt; &lt;br style="color: rgb(255, 0, 0);" /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;20页，表1-2中：&amp;ldquo;可以不出现，也可以只出现一次&amp;rdquo;修改为&amp;ldquo;可以出现，也可以只重现一次&amp;rdquo;；&amp;ldquo;可以出现无数次，也可以不出现&amp;rdquo;修改为&amp;ldquo;可以重现无穷多次，也可以不出现&amp;rdquo;； &amp;ldquo;可以出现无数次，但至少要出现一次&amp;rdquo;修改为&amp;ldquo;可以重现无穷多次，但至少要出现一次&amp;rdquo;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;21页，倒数第2段，&amp;ldquo;这并不是正则表达式的错误&amp;rdquo;应修改为&amp;ldquo;正则表达式对此无能为力&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;27 页，第1段，&amp;ldquo;而且说&amp;ldquo;如果你写一个正则&amp;rdquo;，&amp;ldquo;巧妙的正则&amp;rdquo;（budding regexers），甚至是&amp;ldquo;正则化&amp;rdquo;（regexification）&amp;rdquo;修改为&amp;ldquo;而且说&amp;ldquo;如果你写一个正则&amp;rdquo;，&amp;ldquo;巧妙的正则&amp;rdquo;（budding regexers），甚至是&amp;ldquo;正则化&amp;rdquo;（regexification）听起来更顺一些。我说的&amp;ldquo;正则引擎（regex engine）&amp;rdquo;指的是程序中实际执行匹配尝试的那个部分&amp;rdquo;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;第2章&lt;/p&gt;
&lt;p&gt;37页，第1段，&amp;ldquo;它们都非常不同于&amp;ldquo;传统&amp;rdquo;的预言，例如C和Pascal&amp;rdquo;应修改为&amp;ldquo;它们截然不同于C和Pascal之类&amp;ldquo;传统&amp;rdquo;的预言&amp;rdquo;&lt;/p&gt;
&lt;p&gt;38页，倒数第1段，&amp;ldquo;运算符==用来测试两个数字是否相等&amp;rdquo;修改为&amp;ldquo;运算符==用来测试两个数值是否相等&amp;rdquo;&lt;/p&gt;
&lt;p&gt;40 页，第1段，&amp;ldquo;我不想在本章中讨论Perl的细节，但是我告诉你用printf（&amp;ldquo;格式化输出（print formatted）&amp;rdquo;）可以解决这个问题&amp;rdquo;修改为&amp;ldquo;我不想在本章中讨论Perl的细节，不过我还是想说，printf（&amp;ldquo;格式化输出（print formatted）&amp;rdquo;）可以解决这个问题&amp;rdquo;&lt;/p&gt;
&lt;p&gt;40页，第3段，&amp;ldquo;Perl通常情况下不区分整数和浮点数&amp;rdquo;修改为&amp;ldquo;Perl一般不区分整数和浮点数&amp;rdquo;&lt;/p&gt;
&lt;p&gt;41页，倒数第1段，&amp;ldquo;我们发现，这个图让我们很容易地决定匹配之后应该干什么&amp;rdquo;修改为&amp;ldquo;看了这张图，我们很容易就能决定匹配之后应该干什么&amp;rdquo;&lt;/p&gt;
&lt;p&gt;46页，补充内容的最后1段，&amp;ldquo;尽管因为第4章将会解释其原因，字符组的效率通常还是会高一点&amp;rdquo;修改为&amp;ldquo;不过根据第4章解释的原因，字符组的效率通常要高一些&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;67页，第3段下面，正则表达式&amp;ldquo;$text =~ s/(\d)(?=(\d\d\d)+(?!\d)/$1,/g&amp;rdquo;应修改为&amp;ldquo;$text =~ s/(\d)(?=(\d\d\d)+(?!\d)&lt;/span&gt;&lt;font color="#ff0000" style="color: rgb(255, 0, 0);"&gt;)&lt;/font&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;/$1,/g&amp;rdquo;，少了一个括号&lt;/span&gt;&lt;br style="color: rgb(255, 0, 0);" /&gt; &lt;br style="color: rgb(255, 0, 0);" /&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;70页，第2段，所以整个正则表达式的意义就不再是&amp;ldquo;寻找空行及只包含空白字符的行&amp;rdquo;，而是&amp;ldquo;寻找连续、空行和只包括空白字符的行的结合&amp;rdquo;&lt;/span&gt;&lt;br style="color: rgb(255, 0, 0);" /&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;应修改为&lt;/span&gt;&lt;br style="color: rgb(255, 0, 0);" /&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;所以整个正则表达式的意义就不再是&amp;ldquo;寻找空行或只包含空白字符的行&amp;rdquo;，而是&amp;ldquo;寻找空行和只包含空白字符的行的结合&amp;rdquo;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;76页，倒数第2段，&amp;ldquo;此外，我们的匹配主机名的正则表达式只存在一个&amp;ldquo;主源（main source）&amp;rdquo;&amp;rdquo;应修改为&amp;ldquo;此外，我们的匹配主机名的正则表达式只存在一个&amp;ldquo;源头（main source）&amp;rdquo;，&amp;rdquo;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;第78页&lt;br /&gt;示例2-3中第4标注&lt;br /&gt;{\e[7m$1\e[m$2\e[7m$3\e[m ] igx;&lt;br /&gt;应修改为&lt;br /&gt;{\e[7m$1\e[m$2\e[7m$3\e[m } igx;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;第3章&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;89页，第1段，&amp;ldquo;不支持字符组中的\w（完全不支持\d和\s）&amp;rdquo;应修改为&amp;ldquo;在字符组中无法使用\w（\d和\s在任何地方都无法使用）&amp;rdquo;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;92页，倒数第2段，&amp;ldquo;在极端的情况下，反向引用的&amp;ldquo;行为&amp;rdquo;有意义吗？&amp;rdquo;应修改为&amp;ldquo;在极端的情况下，反向引用还能正常工作吗？&amp;rdquo;&lt;/span&gt;&lt;br /&gt; &lt;br style="color: rgb(255, 0, 0);" /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;95页，标题&amp;ldquo;函数式处理的例子&amp;rdquo;应修改为&amp;ldquo;程序式处理的例子&amp;rdquo;&lt;/span&gt;&lt;br style="color: rgb(255, 0, 0);" /&gt;&lt;br style="color: rgb(255, 0, 0);" /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;95页，倒数第1段，&amp;ldquo;不过，Java也提供了一些函数式处理的&amp;hellip;&amp;hellip;&amp;rdquo;应修改为&amp;ldquo;不过，Java也提供了一些程序式处理的&amp;hellip;&amp;hellip;&amp;rdquo;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;95页，Pattern r = Pattern.compile(&amp;quot;^Sujbcet:(.*)&amp;quot;,Pattern.CASE_INSENSITIVE);&lt;br /&gt;其中的Sujbcet应写为Subject&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;96页，第2段，&amp;ldquo;Sun的package同时提供了程序式和面向对象式的处理方式是常见的做法&amp;rdquo;应修改为&amp;ldquo;Sun的package同时提供了程序式和面向对象式的处理方式，这是种常见的做法&amp;rdquo;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;111页，第1段，&amp;ldquo;常见的例子是大写的&amp;szlig;是两个字符的组合&amp;ldquo;SS&amp;rdquo;。这种情况只有Perl能够正确处理&amp;rdquo;应修改为&amp;ldquo;常见的例子是，大写的&amp;szlig;由两个字符&amp;ldquo;SS&amp;rdquo;组合而成。这种情况只有Perl能够正确处理&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;114页，&amp;ldquo;字符组及相关结构&amp;rdquo;中，&amp;ldquo;字符组缩略表示法&amp;rdquo;应修改为&amp;ldquo;字符组简记法&amp;rdquo;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;130页，3-11表名&amp;ldquo;脚本语言中的行锚点&amp;rdquo;应修改为&amp;ldquo;若干语言中的行锚点&amp;rdquo;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;131页，第1段，&amp;ldquo;如果结合上面那一点&amp;rdquo;应修改为&amp;ldquo;结合第一点&amp;rdquo;&lt;/p&gt;
&lt;p&gt;132页，第3段，&amp;ldquo;但是这段程序的执行单位不是一次表达式而是一次匹配&amp;rdquo;应修改为&amp;ldquo;但是，循环的单位不是单个的表达式，而以一组表达式的匹配&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;134页，&amp;ldquo;中间一级不过是&amp;ldquo;语法（syntactic sugar）&amp;rdquo;，表达方式更美观而已，&amp;rdquo;应修改为&amp;ldquo;中间一级不过是用起来更方便而已（syntactic sugar）&amp;rdquo;&lt;/span&gt;&lt;br style="color: rgb(255, 0, 0);" /&gt;&lt;br /&gt; 第4章&lt;/p&gt;
&lt;p&gt;152页，倒数第1段，括号内，&amp;ldquo;抑制自己的天性&amp;rdquo;应修改为&amp;ldquo;克制自己的本能&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;156 页，第3段，&amp;ldquo;也就是说&amp;ldquo;不到最后关头不能分胜负（It&amp;rsquo;s not over until the fat lady sings）&amp;rdquo;，但这段话又不符合本段的语境&amp;rdquo;&lt;br /&gt;应修改为&lt;br /&gt;&amp;ldquo;也就是说&amp;ldquo;不到最后关头不能分胜负（It&amp;rsquo;s not over until the fat lady sings）&amp;rdquo;&amp;rdquo;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;156页 第3段 第2行&lt;/span&gt;&lt;br style="color: rgb(0, 0, 0);" /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;原文： 即使某个字表达式能够匹配&lt;/span&gt;&lt;br style="color: rgb(0, 0, 0);" /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;应改为：即使某个子表达式能够匹配&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;160页 文字部分的 第5行&lt;br /&gt;原文： 字符串的b之前（也就是当前的位置）匹配&lt;br /&gt;应该为：字符串的c之前（也就是当前的位置）匹配&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;172页，第2段，&amp;ldquo;就可以命令正则引擎不必检查它们：&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;「^(?&amp;gt;\w+)」&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;&amp;rdquo;应修改为&amp;ldquo;&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;就可以命令正则引擎不必检查它们：&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;「^(?&amp;gt;\w+):」&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;&amp;rdquo;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;第5章&lt;/p&gt;
&lt;p&gt;188页 文字部分的 第4段 第2行 结尾&lt;br /&gt;原文： 也不比担心&lt;br /&gt;应该为：也不必担心&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;191页，代码段中的注释大小写错误，&amp;ldquo;#利用正则表达式检测wholePath&amp;rdquo;应修改为&amp;ldquo;#利用正则表达式检测WholePath&amp;rdquo;&lt;/span&gt;&lt;br style="color: rgb(255, 0, 0);" /&gt;&lt;br /&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;195页，倒数第1段，&amp;ldquo;虽然这个表达式比最开始的好得多&amp;rdquo;应修改为&amp;ldquo;虽然这个表达式比开头那个好一些&amp;rdquo;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;197页，第3段，&amp;ldquo;所以，我们得用别的办法来解决&amp;rdquo;应修改为&amp;ldquo;所以，得想点别的办法&amp;rdquo;&lt;/p&gt;
&lt;p&gt;197页，第4段，&amp;ldquo;仔细想想我们想要匹配的位于开始分隔符和结束分隔符之间的文本&amp;rdquo;应修改为&amp;ldquo;仔细想想要匹配的位于开始分隔符和结束分隔符之间的文本&amp;rdquo;&lt;/p&gt;
&lt;p style="color: rgb(255, 0, 0);"&gt;197页，倒数第3段，&amp;ldquo;如果回溯会导致不期望，与多选结构有关的匹配结果&amp;rdquo;应修改为&amp;ldquo;如果回溯会导致不期望的、与多选结构有关的匹配结果&amp;rdquo;&lt;/p&gt;
&lt;p&gt;199页，第5段，&amp;ldquo;这个正则表达式曾被用作降解忽略优先量词的绝佳例子&amp;rdquo;应修改为&amp;ldquo;这个正则表达式曾被用作讲解忽略优先量词的绝佳例子&amp;rdquo;&lt;br /&gt; &lt;br style="color: rgb(255, 0, 0);" /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;199页，倒数第2段，&amp;ldquo;但它并不正确（其实这三个表达式都不正确）&amp;rdquo;应修改为&amp;ldquo;但它并没有错（其实这三个表达式都没有错）&amp;rdquo;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;203页，标题&amp;ldquo;检查HTTP URL&amp;rdquo;应修改为&amp;ldquo;校验HTTP URL&amp;rdquo;，目录中也应同样修改&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;205页，代码段注释中，&amp;ldquo;零个或多个据点分隔的部分&amp;rdquo;应修改为&amp;ldquo;零个或多个点号分隔的部分&amp;rdquo;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;210页 最后一行&lt;br /&gt;原文：导致逆序环视（？！44）失败&lt;br /&gt;应改为：导致否定顺序环视（？！44）失败&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;第6章&lt;/p&gt;
&lt;p&gt;225页，第2段，&amp;ldquo;对于没有转义字符的字符串来说，这样会一次读入整个字符串&amp;rdquo;应修改为&amp;ldquo;不包含转义字符的字符串，会被一次读入&amp;rdquo;&lt;br /&gt; &lt;br style="color: rgb(255, 0, 0);" /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;233页，倒数第1段，&amp;ldquo;所以，对这个例子来说，多选结构要比字符组快22倍左右&amp;rdquo;应修改为&amp;ldquo;所以，对这个例子来说，字符组比多选结构快22倍左右&amp;rdquo;&lt;/span&gt;&lt;br /&gt; &lt;br style="color: rgb(255, 0, 0);" /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;234页，第4段，&amp;ldquo;新增的开销大约花费了5s的时间&amp;rdquo;应修改为&amp;ldquo;新增的开销大约是5秒&amp;rdquo;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;234页 正文部分第2行&lt;/span&gt;&lt;br style="color: rgb(255, 0, 0);" /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;原文：现在，测试字符串只是上面的长度的1/1000，而测试需要进行1000次。&lt;/span&gt;&lt;br style="color: rgb(255, 0, 0);" /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;应该为：现在，测试字符串只是上面的长度的1/1000，而测试需要进行1000000次。&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;246页，第1段，&amp;ldquo;也能够减少传动装置真正应用正则表达式的位置&amp;rdquo;应修改为&amp;ldquo;也能减少传动装置真正应用正则表达式的次数&amp;rdquo;&lt;/p&gt;
&lt;p&gt;266页，第3段，&amp;ldquo;你就能把这几条推广开来&amp;rdquo;应修改为&amp;ldquo;就能把这几条推广开来&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;266页，倒数第4段，&amp;ldquo;事实上，如果点号不能匹配换行符&amp;rdquo;应修改为&amp;ldquo;事实上，如果点号能够匹配换行符&amp;rdquo;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;269页，第1段，&amp;ldquo;不会在匹配时陷入徒劳的尝试&amp;rdquo;应修改为&amp;ldquo;无法匹配时会陷入徒劳的尝试&amp;rdquo;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;274页 上数第4行&lt;br /&gt;原文：紧跟在x之后的斜线&lt;br /&gt;改正：[^x]/ 是紧跟在不是x的字母后面的斜线&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;第7章&lt;/p&gt;
&lt;p&gt;293页，倒数第1段，&amp;ldquo;动态作用域会临时&amp;ldquo;保护&amp;rdquo;全局变量&amp;rdquo;应修改为&amp;ldquo;动态作用域会把全局变量临时&amp;ldquo;遮蔽&amp;rdquo;起来&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;296页，倒数第2段，&amp;ldquo;为方便起见，我们也可以给本地变量赋一个值 local($SomeVar)，这等于把undef赋值给$SomeVar&amp;rdquo;应修改为&amp;ldquo;为方便起见，我们也可以给 local($SomeVar)赋值，这等于给$SomeVar明确赋值，而不是使用undef&amp;rdquo;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;299页，第3段，&amp;ldquo;分散在散落的 local、子程序和本地变量引用之间的复杂交互&amp;rdquo;应修改为&amp;ldquo;分布在散落的 local、子程序和本地变量引用之间的复杂交互&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;300页，正文第1段，&amp;ldquo;你可以期望$ 的起点是开始尝试位置的文本,但它每次都是从整个字符串的开始位置开始的&amp;rdquo;应修改为&amp;ldquo;你可能认为$ 的起点是开始尝试位置的文本，其实它每次都是从整个字符串的开始位置开始的&amp;rdquo;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;301页，倒数第1段，&amp;ldquo;明确设定的$1 等变量中，闭括号在最后&amp;rdquo;应修改为&amp;ldquo;明确设定的$1 等变量中，闭括号在最后的那对括号&amp;rdquo;&lt;/p&gt;
&lt;p&gt;308页，标题&amp;ldquo;指定目标运算元&amp;rdquo;应修改为&amp;ldquo;指定匹配目标运算元&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;326页，第2段，&amp;ldquo;split 没有返回的部分或全部的文本&amp;rdquo;应修改为&amp;ldquo;通常情况下split不会返回的部分或全部的文本&amp;rdquo;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;327页，标题&amp;ldquo;嵌套代码结构&amp;rdquo;应修改为&amp;ldquo;内嵌代码结构&amp;rdquo;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;356页，第1段，&amp;ldquo;不包含捕获型括号的正则表达式可以不必保存拷贝&amp;rdquo;应修改为&amp;ldquo;不包含捕获型括号的正则表达式可以不必保存副本&amp;rdquo;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;361页，第4段，&amp;ldquo;这很适合检查单个的正则表达式的编译方法&amp;rdquo;应修改为&amp;ldquo;这很适合检查单个正则表达式的编译过程&amp;rdquo;&lt;/p&gt;
&lt;p&gt;第8章&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;368页，表8-3倒数第3行，&amp;ldquo;对Unicode字符进行不区分大小写的匹配&amp;rdquo;应修改为&amp;ldquo;对非ASCII字符进行不区分大小写的匹配&amp;rdquo;&lt;/span&gt;&lt;br style="color: rgb(255, 0, 0);" /&gt;&lt;br /&gt; 369页，倒数第4段，&amp;ldquo;Unicode block的支持要求使用&amp;lsquo;In&amp;rsquo;前缀&amp;rdquo;应修改为&amp;ldquo;Unicode区块的支持必须使用&amp;lsquo;In&amp;rsquo;前缀&amp;rdquo;&lt;/p&gt;
&lt;p&gt;371页，第2段，&amp;ldquo;就我个人来说，更喜欢简称前两个为&amp;ldquo;pattern&amp;rdquo;和&amp;ldquo;matcher&amp;rdquo;&amp;rdquo;应修改为&amp;ldquo;我自己更喜欢把前两者简称为&amp;ldquo;pattern&amp;rdquo;和&amp;ldquo;matcher&amp;rdquo;&amp;rdquo;&lt;/p&gt;
&lt;p&gt;374页，倒数第6段，&amp;ldquo;当前pattern的捕获型括号的数目&amp;rdquo;应修改为&amp;ldquo;当前pattern中捕获型括号的数目&amp;rdquo;&lt;/p&gt;
&lt;p&gt;377页 倒数第7行&lt;br /&gt;原文：int end()&lt;br /&gt;次方法返回整个匹配的终点的绝对偏移值&lt;br /&gt;改为：此方法返回整个匹配的终点的绝对偏移值&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;377页，函数&amp;ldquo;String gropu(int num)&amp;rdquo;应修改为&amp;ldquo;String group(int num)&amp;rdquo;&lt;/span&gt;&lt;br style="color: rgb(255, 0, 0);" /&gt;&lt;br /&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;388页，最后一段，&amp;ldquo;即检索范围不等于整个目标字符串&amp;rdquo;应修改为&amp;ldquo;即使检索范围不等于整个目标字符串也是如此&amp;rdquo;&lt;/span&gt;&lt;br style="color: rgb(255, 0, 0);" /&gt;&lt;br /&gt; 389页，标题&amp;ldquo;构建扫描程序&amp;rdquo;应修改为&amp;ldquo;构建扫描程序的方法&amp;rdquo;&lt;/p&gt;
&lt;p&gt;第9章&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;410页，第5段，&amp;ldquo;即用即编译（On-The-Fly Compilation）&amp;rdquo;应修改为&amp;ldquo;直接编译（On-The-Fly Compilation）&amp;rdquo;&lt;/span&gt;&lt;br style="color: rgb(255, 0, 0);" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;410页，倒数第2段，&amp;ldquo;来进行&amp;ldquo;即用即编译&amp;rdquo;的编译&amp;rdquo;应修改为&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;&amp;ldquo;来进行&amp;ldquo;直接编译&amp;rdquo;的编译&amp;rdquo;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt; 432页，标题&amp;ldquo;支持函数&amp;rdquo;应修改为&amp;ldquo;辅助函数&amp;rdquo;&lt;/p&gt;
&lt;p&gt;432页，倒数第4段，&amp;ldquo;还有一些静态的支持函数&amp;rdquo;应修改为&amp;ldquo;还有一些静态辅助函数&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;438页，倒数第3段，&amp;ldquo;尽管涌出并不大&amp;rdquo;应修改为&amp;ldquo;尽管用处并不大&amp;rdquo;&lt;/span&gt;&lt;br style="color: rgb(255, 0, 0);" /&gt;&lt;br /&gt; 第10章&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;442页，第3段，&amp;ldquo;十进制转义只能接受两到三位八位数值&amp;rdquo;应修改为&amp;ldquo;八进制转义只能接受两到三位八进制数字&amp;rdquo;&lt;/span&gt;&lt;br style="color: rgb(255, 0, 0);" /&gt;&lt;br /&gt; 445页，倒数第5段，&amp;ldquo;第448也给出了一个&amp;ldquo;不好&amp;rdquo;的原因&amp;rdquo;应修改为&amp;ldquo;第448页给出了一个&amp;ldquo;不好&amp;rdquo;的理由&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;455页，第3段，&amp;ldquo;这就是默认的配列方式&amp;rdquo;应修改为&amp;ldquo;这就是默认的排列方式&amp;rdquo;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;459页，第3段，&amp;ldquo;这个简单的例子把HTML中的bold tag全部转换为大写&amp;rdquo;应修改为&amp;ldquo;这个简单的例子在HTML中的所有大写单词两端加上bold tag&amp;rdquo;&lt;/span&gt;&lt;br style="color: rgb(255, 0, 0);" /&gt;&lt;br style="color: rgb(255, 0, 0);" /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;459页，倒数第4段，&amp;ldquo;下面这个扩展的例子把bold tag里的单词变为小写&amp;rdquo;应修改为&amp;ldquo;下面这个扩展的例子在添加bold tag的同时把单词转换为小写&amp;rdquo;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;460页的表格，第三行开头应该为&amp;ldquo;数组 数组&amp;rdquo;，第四行开头应该为&amp;ldquo;字符串 数组&amp;rdquo;&lt;/span&gt;&lt;/p&gt;&lt;img src ="http://blog.donews.com/maverick/aggbug/1209937.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>李卫公</dc:creator><title>《精通正则表达式》译者序</title><link>http://blog.donews.com/maverick/archive/2007/08/31/1205082.aspx</link><pubDate>Fri, 31 Aug 2007 09:38:00 GMT</pubDate><guid>http://blog.donews.com/maverick/archive/2007/08/31/1205082.aspx</guid><wfw:comment>http://blog.donews.com/maverick/comments/1205082.aspx</wfw:comment><comments>http://blog.donews.com/maverick/archive/2007/08/31/1205082.aspx#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://blog.donews.com/maverick/comments/commentRss/1205082.aspx</wfw:commentRss><trackback:ping>http://tb.donews.net/TrackBack.aspx?PostId=1205082</trackback:ping><description>&lt;p&gt;&lt;a href="http://www.oreilly.com.cn/book.php?bn=978-7-121-04684-1"&gt;《精通正则表达式（第3版）》&lt;/a&gt;（即Mastering Regular Expression，3rd Edition）是一本好书。&lt;br /&gt; 我还记得，自己刚开始工作时，就遇到了关于正则表达式的问题（从此被逼上梁山）：若从文本中抽取E-mail地址，还可以用字符串来查找（先定位到@，然 后向两端查找），若要抽取URL，简单的文本查找就无能为力了。正当我一筹莫展之时，项目经理说：&amp;ldquo;可以用正则表达式，去网上找找资料吧。&amp;rdquo;抱着这根救命 稻草，我搜索了之前只是听说过名字的正则表达式的资料，并打印了java.util.regex（开发用的Java）的文档来看。摸索了半天，我的感觉就 是，这玩意儿，真神奇，真复杂，真好用。&lt;br /&gt; 此后，用到正则表达式的地方越来越多，我也越来越感觉到它的重要，然而使用起来却总感觉捉襟见肘。当时是夏天，北京非常热，我决定下班之后不再着急赶车回家，而是在公司安心看看技术文档，于是邂逅了这本&lt;a href="http://www.amazon.com/Mastering-Regular-Expressions-Jeffrey-Friedl/dp/0596528124/ref=sr_11_1/104-7541332-0393550?ie=UTF8&amp;amp;qid=1184290193&amp;amp;sr=11-1"&gt;Mastering Regular Expression&lt;/a&gt;。该书原文是相当通畅易懂的，看完全书大概花了我一周的业余时间，之后便如拨云见日，感觉别有洞天&amp;mdash;&amp;mdash;原来正则表达式可以这样用，真是奇妙，真是令人拍案叫绝。&lt;br /&gt; 此后我运用正则表达式便不用再看什么资料了，充其量就是查查语言的具体文档，表达式的基本模型和思路，完全是在阅读本书时确立的。也正是因为细心阅读过本书，所以有时我能以正则表达式解决某些复杂的问题。我的朋友&lt;a href="http://www.tinydust.net/prog/diary/diary.htm"&gt;郝培强&lt;/a&gt;（Tinyfool， 昵称Tiny）曾问过我这样一个正则表达式的问题：在Apache服务器的Rewrite规则中，要求以一个正则表达式匹配&amp;ldquo;除两个特定子域名之外的所有 其他子域名&amp;rdquo;，其他人的办法都无法满足要求：要么只能匹配这两个特定的子域名，要么必须依赖程序分支才能进行判断。其实这个问题，是可以用一个正则表达式 匹配的。事后，Tiny说，看来，会用正则的人很多，但真正懂得正则的人很少。现实情况也确实如此，就我所见，不少同仁对正则表达式的运用，不外乎从网上 找一些现成的表达式，套用在自己的程序中，但对到底该用几个反斜线转义，转义是在字符串级别还是表达式级别进行的，捕获型括号是否必须，表达式的效率如 何，等等问题，往往都是一知半解，甚至毫无概念，在Tiny的问题面前，更是束手无策，一筹莫展。&lt;br /&gt; 就我个人来说，我所掌握的正则表达式的知识，绝大多数来自本书。正是依靠这些知识，我几乎能以正则表达式进行自己期望的任何文本处理，所以我相信，能够耐 心读完这本书的读者，一定能深入正则表达式的世界，若再加以练习和思考，就能熟练地依靠它解决各种复杂的问题（其中就包括类似Tiny的问题）了。&lt;br /&gt; 去年，通过&lt;a href="http://blog.devep.net/virushuo/"&gt;霍炬（Virushuo）&lt;/a&gt;的 介绍，我参加了博文视点的试译活动，很幸运地获得了翻译本书的机会。有机会与大家分享这样一本好书，我深感荣幸。500多页的书，拖拖拉拉，也花了半年多 的时间。虽然之前读过原著，积累了一些运用正则表达式的经验，也翻译过数十万字的资料，但要尽可能准确、贴切地传达原文的阅读感觉，我仍感颇费心力。部分 译文在确认理解原文的基础上，要以符合中文习惯的方式加以表述仍然颇费周折（例如，直译的&amp;ldquo;正则表达式确实容许出现这种错误&amp;rdquo;，原文的意思是&amp;ldquo;这样的错误 超出了正则表达式的能力&amp;rdquo;，最后修改为&amp;ldquo;出现这样的错误，不能怪正则表达式&amp;rdquo;或&amp;ldquo;这样的问题，错不在正则表达式&amp;rdquo;）。另有部分词语，虽可译为中文，但为保 证阅读的流畅，没有翻译（例如，&amp;ldquo;它包含特殊和一般两个部分，特殊部分之所以是特殊的，原因在于&amp;hellip;&amp;hellip;&amp;rdquo;，此处special和normal是专指，故翻译 为&amp;ldquo;它包含special和normal两个部分，special部分之所以得名，原因在于&amp;hellip;&amp;hellip;&amp;rdquo;），这样的处理，相信不会影响读者的理解。&lt;br /&gt; 在本书翻译结束之际，我首先要感谢霍炬，他的引荐让我获得了翻译这本书的机会；还要感谢博文视点的周筠老师，她谨慎严格的工作态度，时刻提醒我不能马虎对待这本经典之作；还有本书的责编晓菲，她为本书的编辑和校对做了大量细致而深入的工作。&lt;br /&gt; 另外我还要感谢东北师范大学文学院的王确老师，在我求学期间，王老师给予我诸多指点，离校时间愈长，愈是怀念和庆幸那段经历，可以说，没有与他的相识，便没有我的今天。&lt;br /&gt; 本书是讲授正则表达式的经典之作，翻译过程中，我虽力求把握原文，语言通畅，但翻译中的错误或许是在所难免的，对此本人愿负全部责任。希望广大读者发现错 误能及时与我和出版社联系以便再版时修正，或是以勘误的形式公布出来以惠及其他读者。如果读者有任何想法或建议，欢迎给我写信，我的邮件地址是： yusheng.regex@gmail.com。&lt;/p&gt;
&lt;p&gt;&lt;span id="more-193"&gt;&lt;/span&gt;&lt;br /&gt; 如今正则表达式已经成为几乎所有主流编程语言中的必备元素：Java、Perl、Python、PHP、Ruby&amp;hellip;&amp;hellip;莫不如此，甚至功能稍强大一些的文本 编辑工具，都支持正则表达式。尤其是在Web兴起之后，开发任务中的一大部分甚至全部，都是对字符串的处理。相比简单的字符串比较、查找、替换，正则表达 式提供了强大得多的处理能力（最重要的是，它能够处理&amp;ldquo;符合某种抽象模式&amp;rdquo;的字符串，而不是固化的、具体的字符串）。熟练运用它们，能够节省大量的开发时 间，甚至解决一些之前看来是mission impossible的问题。&lt;br /&gt; 本书是讲解正则表达式的经典之作。其他介绍正则表达式的资料，往往局限于具体的语法和函数的讲解，于语法细节处着墨太多，忽略了正则表达式本身。这样，读 者虽然对关于正则表达式的具体规定有所了解，但终究是只见树木不见森林，遇上复杂的情况，往往束手无策，举步维艰。而本书自第1版开始便着力于教会读者 &amp;ldquo;以正则表达式来思考（think regular expression）&amp;rdquo;，向读者讲授正则表达式的精髓（正则表达式的各种流派、匹配原理、优化原则，等等），而不拘泥于具体的规定和形式。了解这些精 髓，再辅以具体操作的文档，读者便可做到&amp;ldquo;胸中有丘壑，下笔如有神&amp;rdquo;；即便问题无法以正则表达式来解决，读者也能很快作出判断，而不必盲目尝试，徒费工 夫。&lt;br /&gt; 不了解正则表达式的读者，可循序渐进，依次阅读各章，即便之前完全未接触过正则表达式，读过前两章，也能在心中描绘出概略的图谱。第3、4、5、6章是本 书的重点，也是核心价值所在，它们分别介绍了正则表达式的特性和流派、匹配原理、实用诀窍以及调校措施。这样的知识与具体语言无关，适用于几乎所有的语言 和工具（当然，如果使用DFA引擎，第6章的价值要打些折扣），所谓&amp;ldquo;大象无形&amp;rdquo;，便是如此。读者如能仔细研读，悉心揣摩，之后解决各种问题时，必定获益 匪浅。第7、8、9、10章分别讲解了Perl、Java、.NET、PHP中正则表达式的用法，看来类似参考手册，其实是对前面4章知识的包装，将抽象 的知识辅以具体的语言规定，以具体的形式表现出来。所以，心急的读者，在阅读这些章节之前，最好先通读第3、4、5、6章，以便更好地理解其中的逻辑和思 路。&lt;br /&gt; 相信仔细阅读完本书的读者，定会有登堂入室的感觉。不但能见识到正则表达式各种令人眼花缭乱的特性，更能够深入了解表达式、匹配、引擎背后的原理，从而写出复杂、神奇而又高效的正则表达式，快速地解决工作中的各种问题。&lt;/p&gt;
&lt;p&gt;余晟&lt;br /&gt; 2007年6月于北京&lt;/p&gt;&lt;img src ="http://blog.donews.com/maverick/aggbug/1205082.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>李卫公</dc:creator><title>开发笔记：关于一个函数的讨论</title><link>http://blog.donews.com/maverick/archive/2007/08/21/1201383.aspx</link><pubDate>Tue, 21 Aug 2007 16:42:00 GMT</pubDate><guid>http://blog.donews.com/maverick/archive/2007/08/21/1201383.aspx</guid><wfw:comment>http://blog.donews.com/maverick/comments/1201383.aspx</wfw:comment><comments>http://blog.donews.com/maverick/archive/2007/08/21/1201383.aspx#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://blog.donews.com/maverick/comments/commentRss/1201383.aspx</wfw:commentRss><trackback:ping>http://tb.donews.net/TrackBack.aspx?PostId=1201383</trackback:ping><description>朋友问这样的问题：&lt;br /&gt;写了一个函数，从网页源代码中抽取一个结点的文本，函数本身没有问题，但同事在code review时指出，如果提取不成功，应该返回None，而不是空字符串&amp;quot;&amp;quot;。&lt;br /&gt;&lt;br /&gt;提问的朋友跟我说：你之前说过，从数据库里取出一批数据，如果不存在，要返回一个空的Collection，而不是None（这样才能正确表示&amp;ldquo;需要的数据不存在&amp;rdquo;），那么这里，是否应该听取同事的意见呢？&lt;br /&gt;当时我的回答是，因为从这个函数接受数据的代码期望获得的是一个字符串，所以，如果提取不成功，应该返回&amp;quot;&amp;quot;。&lt;br /&gt;但是，这样，就无法区分下面两种情况了：存在这个结点，但是一个空结点；不存在这个结点。&lt;br /&gt;&lt;br /&gt;这几天晚上一直在思考这个问题，并与&lt;a href="http://blog.csdn.net/holy_phoenix"&gt;Patrick&lt;/a&gt;讨论，最后的结论是：&lt;br /&gt;之所以会出现这个问题，原因在于函数的定义是不明确的&amp;mdash;&amp;mdash;虽然函数名看来很清楚，但它的意义是不确定的。&lt;br /&gt;按照&lt;a href="http://blog.donews.com/maverick/archive/2006/04/22/841290.aspx"&gt;契约式设计(Design by Contract)&lt;/a&gt;的原则，每个模块都应该有前驱条件(pre-condition)和后继条件(post-condition)。正是因为两位开发人员对这一点的认识存在分歧，问题才会出现：&lt;br /&gt;
&lt;ul&gt;
    &lt;li&gt;如果这个函数的前驱条件是，必须提供一段包含此结点的源代码（也就是说，这个结点必须存在），就不能返回None，返回&amp;quot;&amp;quot;，就表示这个结点内容为空，如果提供的源代码不包含这个结点，应抛出异常；&lt;/li&gt;
    &lt;li&gt;如果前驱条件是，提供的源代码不必包含这个结点，那么，这个函数其实就履行了两项职责&amp;mdash;&amp;mdash;检查是否存在结点，以及提取结点的文本，必须与调用方有一个约定，来表示这两重含义（此时可以用None表示&amp;ldquo;不存在结点&amp;rdquo;的情况，用&amp;quot;&amp;quot;表示结点内容为空的情况，当然我不推荐这么做）。&lt;/li&gt;
&lt;/ul&gt;
同样，按照契约式设计的原则，数据验证的职责在调用方，也就是说，约定了这个函数的前驱和后继条件之后，调用方在调用之前，必须保证前驱条件：如果函数要求源代码必须包含这个结点，那么验证是否存在的职责就应该由调用方来承担。&lt;img src ="http://blog.donews.com/maverick/aggbug/1201383.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>李卫公</dc:creator><title>我感觉不到任何乐趣</title><link>http://blog.donews.com/maverick/archive/2007/08/08/1195220.aspx</link><pubDate>Wed, 08 Aug 2007 10:27:00 GMT</pubDate><guid>http://blog.donews.com/maverick/archive/2007/08/08/1195220.aspx</guid><wfw:comment>http://blog.donews.com/maverick/comments/1195220.aspx</wfw:comment><comments>http://blog.donews.com/maverick/archive/2007/08/08/1195220.aspx#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://blog.donews.com/maverick/comments/commentRss/1195220.aspx</wfw:commentRss><trackback:ping>http://tb.donews.net/TrackBack.aspx?PostId=1195220</trackback:ping><description>看了这个视频，感觉不到任何乐趣，只看到愚蠢、低级和庸俗。&lt;br /&gt;如果说，好端端的一个节目，央视来办就会办砸，办到傻气四溢趣味全无，那么，现在谷歌可以高傲地宣称，他们已经超过了央视。呆若木鸡的表情，粗制滥造的台词，了无新意的情节，如果果真是谷歌春节晚会的节目，那么我们只能说，这是一群远离高尚的人，一群很难说是纯粹的人，一群分不清底线的人，一群没有脱离低级趣味的人。Google高高在上的金字招牌，更像是他们华丽的裹尸布&amp;mdash;&amp;mdash;原来神圣的光环之后，竟然隐藏着这样的龌龊。&lt;br /&gt;&lt;br /&gt;或许，谷歌已经深得炒作之道，作一次芙蓉姐姐，收获天量的眼球？&lt;br /&gt;&lt;br /&gt;到底是谁恶搞了谁？&lt;br /&gt;  &lt;embed width="450" height="372" align="middle" type="application/x-shockwave-flash" allowscriptaccess="sameDomain" quality="high" src="http://player.youku.com/player.php/sid/XNjk5NzU4OA==/v.swf"&gt;&lt;/embed&gt;&lt;img src ="http://blog.donews.com/maverick/aggbug/1195220.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>李卫公</dc:creator><title>一个Shell脚本的三次改进</title><link>http://blog.donews.com/maverick/archive/2007/08/06/1194418.aspx</link><pubDate>Mon, 06 Aug 2007 17:50:00 GMT</pubDate><guid>http://blog.donews.com/maverick/archive/2007/08/06/1194418.aspx</guid><wfw:comment>http://blog.donews.com/maverick/comments/1194418.aspx</wfw:comment><comments>http://blog.donews.com/maverick/archive/2007/08/06/1194418.aspx#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://blog.donews.com/maverick/comments/commentRss/1194418.aspx</wfw:commentRss><trackback:ping>http://tb.donews.net/TrackBack.aspx?PostId=1194418</trackback:ping><description>最近需要迁移CVS服务器，需要将project中的CVS目录全部删除。这项工作非常繁琐，所以我希望用Shell脚本来完成。&lt;br /&gt;最先想到的是经典的&amp;ldquo;递归查找&amp;rdquo;思路，按照层序遍历整个目录，找到CVS目录，就删除&lt;br /&gt;&lt;hr style="width: 100%; height: 2px;" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;#!/bin/sh &lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;function processFile {&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if [ -d $1 ]; then &lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for currentFile in $1/* &lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; do &lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if [ -d &amp;quot;$currentFile&amp;quot; ]; then &lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; contain=$(echo &amp;quot;$currentFile&amp;quot; | grep 'CVS$')&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if [ -n &amp;quot;$contain&amp;quot; ]; then &lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; echo &amp;quot;rm -rf $currentFile&amp;quot;&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; processFile &amp;quot;$currentFile&amp;quot;&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fi&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fi&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; done&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; fi&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;}&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt; &lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;processFile $1&lt;/span&gt;&lt;br /&gt;&lt;hr style="width: 100%; height: 2px;" /&gt;忽然我想到Shell中的find命令可以递归地查找所有的目录，于是可以这样获得所有CVS目录&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;#之所以要在后面添加grep，是为了确保目录结尾为CVS&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;find . -name 'CVS' | grep 'CVS$' &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;那么接下来我们只需要依次删除这条命令输出的各个目录就好了，但是rm命令似乎又无法接收多行（或者是我不知道），只好先拼成一行再传过去（如果太长，可以用for循环来处理）&lt;br /&gt;&lt;hr style="width: 100%; height: 2px;" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;#!/bin/sh&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;cvsDirs=$(find . -name 'CVS' | grep 'CVS$' | sed -e 's/\n//g' | awk 'BEGIN {fileStr=&amp;quot;&amp;quot;} {fileStr=fileStr&amp;quot; &amp;quot;$0} END {print fileStr}')&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;rm -rf $cvsDirs&lt;/span&gt;&lt;br /&gt;&lt;hr style="width: 100%; height: 2px;" /&gt;还是很复杂&lt;br /&gt;&lt;br /&gt;最后我发现了更好的办法，对于导出的每个CVS目录，我们只需要在前面添加&lt;span style="color: rgb(0, 0, 255);"&gt;rm -rf&lt;/span&gt;命令，就可以删除了&lt;br /&gt;&lt;br /&gt;所以，最后就是一句话：&lt;br /&gt;&lt;hr style="width: 100%; height: 2px;" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;#!/bin/sh&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;find . -name 'CVS' | grep 'CVS$' | sed -e 's/^/rm -rf /g' | /bin/sh&lt;/span&gt;&lt;hr style="width: 100%; height: 2px;" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;/span&gt;&lt;img src ="http://blog.donews.com/maverick/aggbug/1194418.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>李卫公</dc:creator><title>更换Ubuntu自带的ALSA驱动，获得更好的音质</title><link>http://blog.donews.com/maverick/archive/2007/08/06/1194204.aspx</link><pubDate>Mon, 06 Aug 2007 12:30:00 GMT</pubDate><guid>http://blog.donews.com/maverick/archive/2007/08/06/1194204.aspx</guid><wfw:comment>http://blog.donews.com/maverick/comments/1194204.aspx</wfw:comment><comments>http://blog.donews.com/maverick/archive/2007/08/06/1194204.aspx#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://blog.donews.com/maverick/comments/commentRss/1194204.aspx</wfw:commentRss><trackback:ping>http://tb.donews.net/TrackBack.aspx?PostId=1194204</trackback:ping><description>很久没有用音箱听音乐，周末本来准备去买一对惠威M200 MK2，之前先试试已经服役7年的Creative Soundworks SW300，却发现T60的声卡在Ubuntu下的音质比Windows下差很多，买音箱的念头只好暂时作罢。&lt;br /&gt;不甘心地在网上搜索了半天，找了个办法，自己编译一个ALSA驱动，更换Ubuntu自带的驱动，换上去听听，确实有了不小的进步，以下是操作步骤：&lt;br /&gt;&lt;br /&gt;首先，获取编译需要的软件包：&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;sudo apt-get install build-essential ncurses-dev gettext&lt;/span&gt;&lt;br /&gt;然后&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;sudo apt-get install linux-headers-`uname -r`&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;在编译替换之前，必须首先停止当前的ALSA服务：&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;sudo /etc/init.d/alsa-utils stop&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;sudo /etc/init.d/alsasound stop&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;现在创建一个目录，用于编译alsa的驱动&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;mkdir alsa-src&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;cd alsa-src&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;br /&gt;然后下载&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;wget ftp://ftp.alsa-project.org/pub/driver/alsa-driver-1.0.14rc3.tar.bz2&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;wget ftp://ftp.alsa-project.org/pub/lib/alsa-lib-1.0.14rc3.tar.bz2&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;wget ftp://ftp.alsa-project.org/pub/utils/alsa-utils-1.0.14rc2.tar.bz2&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;解包&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;tar xvjf alsa-driver-1.0.14rc3.tar.bz2&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;tar xvjf alsa-lib-1.0.14rc3.tar.bz2&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;tar xvjf alsa-utils-1.0.14rc2.tar.bz2&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;在编译之前，还要下载对应的补丁文件&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;wget http://lenovo.dropshock.com/files/realtek6.tar.gz&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;用补丁文件替换源文件&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;tar xvzf realtek6.tar.gz&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;cp patch_realtek.c ~/alsa-src/alsa-driver-1.0.14rc3/alsa-kernel/pci/hda/&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;现在开始编译&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;cd alsa-driver-1.0.14rc3&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;./configure --with-cards=hda-intel&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;make&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;sudo make install&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;cd ../alsa-lib-1.0.14rc3&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;./configure&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;sudo make install&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;cd ../alsa-utils-1.0.14rc2&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;./configure&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;sudo make install&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;好了，编译完成，剩下的就是替换掉原有的alsa驱动&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;sudo modprobe -r snd-hda-intel &amp;amp;&amp;amp; sudo modprobe snd-hda-intel&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;重新启动alsa&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;sudo /etc/init.d/alsa-utils restart&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;sudo /etc/init.d/alsasound restart&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;br /&gt;然后重新启动Ubuntu，可能会发现音量图标上有个红叉，需要在音量控制界面中将PCM的静音取消。&lt;br /&gt;再听听，音质果然好了不少。&lt;img src ="http://blog.donews.com/maverick/aggbug/1194204.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>李卫公</dc:creator><title>开发笔记：Python中的Module</title><link>http://blog.donews.com/maverick/archive/2007/07/02/1182018.aspx</link><pubDate>Mon, 02 Jul 2007 17:57:00 GMT</pubDate><guid>http://blog.donews.com/maverick/archive/2007/07/02/1182018.aspx</guid><wfw:comment>http://blog.donews.com/maverick/comments/1182018.aspx</wfw:comment><comments>http://blog.donews.com/maverick/archive/2007/07/02/1182018.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blog.donews.com/maverick/comments/commentRss/1182018.aspx</wfw:commentRss><trackback:ping>http://tb.donews.net/TrackBack.aspx?PostId=1182018</trackback:ping><description>Python中的Module是比较重要的概念。常见的情况是，事先写好一个.py文件，在另一个文件中需要import时，将事先写好的.py文件拷贝到当前目录，或者是在sys.path中增加事先写好的.py文件所在的目录，然后import。这样的做法，对于少数文件是可行的，但如果程序数目很多，层级很复杂，就很吃力了。&lt;br /&gt;有没有办法，像Java的Package一样，将多个.py文件组织起来，以便在外部统一调用，和在内部互相调用呢？答案是有的。&lt;br /&gt;&lt;br /&gt;要弄明白这个问题，首先要知道，Python在执行import语句时，到底进行了什么操作，按照Python的文档，它执行了如下操作：&lt;br /&gt;第1步，创建一个新的，空的module对象（它可能包含多个module）；&lt;br /&gt;第2步，把这个module对象插入sys.module中&lt;br /&gt;第3步，装载module的代码（如果需要，首先必须编译）&lt;br /&gt;第4步，执行新的module中对应的代码。&lt;br /&gt;&lt;br /&gt;在执行第3步时，首先要找到module程序所在的位置，其原理为：&lt;br /&gt;如果需要导入的module的名字是m1，则解释器必须找到m1.py，它首先在当前目录查找，然后是在环境变量PYTHONPATH中查找。PYTHONPATH可以视为系统的PATH变量一类的东西，其中包含若干个目录。如果PYTHONPATH没有设定，或者找不到m1.py，则继续搜索与Python的安装设置相关的默认路径，在Unix下，通常是/usr/local/lib/python。&lt;br /&gt;事实上，搜索的顺序是：当前路径（以及从当前目录指定的sys.path），然后是PYTHONPATH，然后是Python的安装设置相关的默认路径。正因为存在这样的顺序，如果当前路径或PYTHONPATH中存在与标准module同样的module，则会覆盖标准module。也就是说，如果当前目录下存在xml.py，那么执行import xml时，导入的是当前目录下的module，而不是系统标准的xml。&lt;br /&gt;&lt;br /&gt;了解了这些，我们就可以先构建一个package，以普通module的方式导入，就可以直接访问此package中的各个module了。&lt;br /&gt;&lt;br /&gt;Python中的package定义很简单，其层次结构与程序所在目录的层次结构相同，这一点与Java类似，唯一不同的地方在于，Python中的package必须包含一个__init__.py的文件。&lt;br /&gt;例如，我们可以这样组织一个package:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;package1/&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; __init__.py&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; subPack1/&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; __init__.py&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; module_11.py&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; module_12.py&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; module_13.py&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; subPack2/&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; __init__.py&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; module_21.py&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; module_22.py&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;hellip;&amp;hellip;&lt;br /&gt;&lt;br /&gt;__init__.py可以为空，只要它存在，就表明此目录应被作为一个package处理。当然，__init__.py中也可以设置相应的内容，下文详细介绍。&lt;br /&gt;&lt;br /&gt;好了，现在我们在module_11.py中定义一个函数：&lt;br /&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;def funA():&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; print &amp;quot;funcA in module_11&amp;quot;&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;在顶层目录（也就是package1所在的目录，当然也参考上面的介绍，将package1放在解释器能够搜索到的地方）运行Python:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;&amp;gt;&amp;gt;&amp;gt;from package1.subPack1.module_11 import funcA&lt;/span&gt;&lt;br style="color: rgb(255, 0, 0);" /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;&amp;gt;&amp;gt;&amp;gt;funcA()&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;funcA in module_11&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;这样，我们就按照package的层次关系，正确调用了module_11中的函数。&lt;br /&gt;&lt;br /&gt;细心的用户会发现，有时在import语句中会出现通配符*，导入某个module中的所有元素，这是怎么实现的呢？&lt;br /&gt;答案就在__init__.py中。我们在subPack1的__init__.py文件中写&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;__all__ = ['module_13', 'module_12']&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;然后进入Python&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&amp;gt;&amp;gt;from package1.subPack1 import *&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;&amp;gt;&amp;gt;&amp;gt;module_11.funcA()&lt;/span&gt;&lt;br style="color: rgb(255, 0, 0);" /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;Traceback (most recent call last):&lt;/span&gt;&lt;br style="color: rgb(255, 0, 0);" /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;&amp;nbsp; File &amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;, line 1, in &amp;lt;module&amp;gt;&lt;/span&gt;&lt;br style="color: rgb(255, 0, 0);" /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;ImportError: No module named module_11&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;也就是说，以*导入时，package内的module是受__init__.py限制的。&lt;br /&gt;&lt;br /&gt;好了，最后来看看，如何在package内部互相调用。&lt;br /&gt;如果希望调用同一个package中的module，则直接import即可。也就是说，在module_12.py中，可以直接使用&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;import module_11&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;如果不在同一个package中，例如我们希望在module_21.py中调用module_11.py中的FuncA，则应该这样：&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;from package1.subPack1.module_11 import funcA&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;当然，在Python 2.5中，有更简单的办法：&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;from .. subPack1.module_11 import funcA&lt;/span&gt;&lt;img src ="http://blog.donews.com/maverick/aggbug/1182018.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>李卫公</dc:creator><title>开发笔记：Python中的全局变量</title><link>http://blog.donews.com/maverick/archive/2007/07/02/1181907.aspx</link><pubDate>Mon, 02 Jul 2007 14:14:00 GMT</pubDate><guid>http://blog.donews.com/maverick/archive/2007/07/02/1181907.aspx</guid><wfw:comment>http://blog.donews.com/maverick/comments/1181907.aspx</wfw:comment><comments>http://blog.donews.com/maverick/archive/2007/07/02/1181907.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blog.donews.com/maverick/comments/commentRss/1181907.aspx</wfw:commentRss><trackback:ping>http://tb.donews.net/TrackBack.aspx?PostId=1181907</trackback:ping><description>全局变量不符合参数传递的精神，所以，平时我很少使用，除非定义常量。今天有同事问一个关于全局变量的问题，才发现其中原来还有门道。&lt;br /&gt;&lt;br /&gt;程序大致是这样的：&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;CONSTANT = 0&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;def modifyConstant() :&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print CONSTANT&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CONSTANT += 1&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if __name__ == '__main__' :&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; modifyConstant()&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print CONSTANT&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;运行结果如下：&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;UnboundLocalError: local variable 'CONSTANT' referenced before assignment&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;看来，全局变量在函数modifyConstant中边成了局部变量，似乎全局变量没有生效？&lt;br /&gt;做点修改：&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;CONSTANT = 0&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;def modifyConstant() :&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print CONSTANT&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ＃CONSTANT += 1&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if __name__ == '__main__' :&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; modifyConstant()&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print CONSTANT&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;运行正常，看来函数内部是可以访问全局变量的。&lt;br /&gt;所以，问题就在于，因为在函数内部修改了变量CONSTANT，Python认为CONSTANT是局部变量，而print CONSTANT又在CONSTANT += 1之前，所以当然会发生这种错误。&lt;br /&gt;&lt;br /&gt;那么，应该如何在函数内部访问并修改全局变量呢？应该使用关键字global来修饰变量（有点像PHP）：&lt;br /&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;CONSTANT = 0&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;def modifyConstant() :&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: rgb(0, 0, 255); font-weight: bold;"&gt;global &lt;/span&gt;CONSTANT&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print CONSTANT&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CONSTANT += 1&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if __name__ == '__main__' :&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; modifyConstant()&lt;/span&gt;&lt;br style="color: rgb(0, 0, 255);" /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print CONSTANT&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;就这么简单！&lt;img src ="http://blog.donews.com/maverick/aggbug/1181907.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>李卫公</dc:creator><title>开发笔记：在Ubuntu下安装JDK 6和Eclipse</title><link>http://blog.donews.com/maverick/archive/2007/05/22/1167648.aspx</link><pubDate>Tue, 22 May 2007 18:31:00 GMT</pubDate><guid>http://blog.donews.com/maverick/archive/2007/05/22/1167648.aspx</guid><wfw:comment>http://blog.donews.com/maverick/comments/1167648.aspx</wfw:comment><comments>http://blog.donews.com/maverick/archive/2007/05/22/1167648.aspx#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://blog.donews.com/maverick/comments/commentRss/1167648.aspx</wfw:commentRss><trackback:ping>http://tb.donews.net/TrackBack.aspx?PostId=1167648</trackback:ping><description>首先需要安装JDK 6&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;sudo apt-get install sun-java6-jdk&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;之后需要设置默认的java程序&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;sudo update-alternatives --config java&lt;/span&gt;&lt;br /&gt;按照提示输入对应的选项，指定为JDK 6&lt;br /&gt;&lt;br /&gt;下面设置&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;sudo vim /etc/environment&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;在其中添加如下两行：&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;CLASSPATH=/usr/lib/jvm/java-6-sun/lib&lt;/span&gt;&lt;br style="color: rgb(255, 0, 0);" /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;JAVA_HOME=/usr/lib/jvm/java-6-sun&lt;/span&gt;&lt;br /&gt;如果其中已经设置了CLASSPATH和JAVA_HOME，则将其修改为上面的形式，按ZZ保存退出。&lt;br /&gt;&lt;br /&gt;接下来安装Eclipse&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;sudo apt-get install eclipse&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;需要注意的是，此时Eclipse并不关心之前设置的update-alternative&lt;br /&gt;&lt;br /&gt;所以应该修改Eclipse的配置。首先将 SUN-JDK-6彻底设为系统默认：&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;sudo update-java-alternatives -s java-6-sun&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;然后编辑JVM配置文件：&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;sudo vim /etc/jvm&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;在文件顶部添加&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;/usr/lib/jvm/java-6-sun&lt;/span&gt;&lt;br /&gt;（如果没有则自己新建）&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;sudo vim /etc/eclipse/java_home&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;也是在文件顶部添加&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;/usr/lib/jvm/java-6-sun &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;之后启动Eclipse，选择Help-&amp;gt;About Eclipse SDK，选择Configuration Details，可以看到JDK6的设置已经生效。&lt;img src ="http://blog.donews.com/maverick/aggbug/1167648.aspx" width = "1" height = "1" /&gt;</description></item></channel></rss>