<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>我爱正则表达式 &#187; rex</title>
	<atom:link href="http://iregex.org/blog/author/admin/feed" rel="self" type="application/rss+xml" />
	<link>http://iregex.org</link>
	<description>原创、翻译、转载关于正则表达式的文章</description>
	<lastBuildDate>Fri, 30 Mar 2012 12:50:01 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
<atom:link rel="hub" href="http://pubsubhubbub.appspot.com"/><atom:link rel="hub" href="http://superfeedr.com/hubbub"/><atom:link rel="hub" href="http://www.feedsky.com/api/RPC2"/><atom:link rel="hub" href="http://blogsearch.google.com/ping/RPC2"/><atom:link rel="hub" href="http://blog.yodao.com/ping/RPC2"/><atom:link rel="hub" href="http://www.feedsky.com/api/RPC2"/><atom:link rel="hub" href="http://www.xianguo.com/xmlrpc/ping.php"/><atom:link rel="hub" href="http://www.zhuaxia.com/rpc/server.php"/><atom:link rel="hub" href="http://rpc.technorati.com/rpc/ping"/><atom:link rel="hub" href="http://rpc.pingomatic.com/"/>		<item>
		<title>较安全的rm脚本</title>
		<link>http://iregex.org/blog/safer-rm-command.html</link>
		<comments>http://iregex.org/blog/safer-rm-command.html#comments</comments>
		<pubDate>Tue, 29 Mar 2011 05:00:18 +0000</pubDate>
		<dc:creator>rex</dc:creator>
				<category><![CDATA[应用]]></category>

		<guid isPermaLink="false">http://iregex.org/?p=155</guid>
		<description><![CDATA[想必不少人体会过在Linux下误删文件的欲哭无泪的感觉。我整理出一份比较安全的rm脚本，贴在这里。 特性 接管原生的/bin/rm命令，将待删除的文件mv至回收站，便于统一管理，或者更重要的，... ]]></description>
			<content:encoded><![CDATA[<p>想必不少人体会过在Linux下误删文件的欲哭无泪的感觉。我整理出一份比较安全的rm脚本，贴在这里。</p>
<p><span id="more-155"></span></p>
<h2 style="background-color: rgb(153, 204, 0); border: 1px solid rgb(102, 102, 102); color: rgb(0, 0, 0); font-size: 21px; line-height: 35px; padding-top: 3px; text-indent: 6px;">特性</h2>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<ul>
<li>接管原生的<code class="codecolorer bash default"><span class="bash"><span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">rm</span></span></code>命令，将待删除的文件<code class="codecolorer bash default"><span class="bash"><span style="color: #c20cb9; font-weight: bold;">mv</span></span></code>至回收站，便于统一管理，或者更重要的，拯救误删文件。</li>
<li>需要调用原生的<code class="codecolorer bash default"><span class="bash"><span style="color: #c20cb9; font-weight: bold;">rm</span></span></code>时，指定路径即可，例如：<code class="codecolorer bash default"><span class="bash"><span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #660033;">-rf</span> somefolder</span></code> </li>
<li>记录删除日志到<code class="codecolorer bash default"><span class="bash"><span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>log<span style="color: #000000; font-weight: bold;">/</span>trash.log</span></code>。如果不需要记录日志，只需要将<code class="codecolorer bash default"><span class="bash">log</span></code>变量置空即可。 </li>
<li>将文件移动至回收站时自动重命名，以便可以重复删除重名文件。</li>
<li>贴图：<img src="http://i293.photobucket.com/albums/mm60/zhasm/iregex/Screenshot2011-03-29at123750PM.png" alt="我爱正则表达式" /></li>
</ul>
</blockquote>
<h2 style="background-color: rgb(153, 204, 0); border: 1px solid rgb(102, 102, 102); color: rgb(0, 0, 0); font-size: 21px; line-height: 35px; padding-top: 3px; text-indent: 6px;">贴代码</h2>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">用法</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<li>将下面的代码贴至<code class="codecolorer bash default"><span class="bash">~<span style="color: #000000; font-weight: bold;">/</span>.bashrc 或 ~<span style="color: #000000; font-weight: bold;">/</span>.bash_profile</span></code>中，然后刷新该文件<code class="codecolorer bash default"><span class="bash"><span style="color: #7a0874; font-weight: bold;">source</span> ~<span style="color: #000000; font-weight: bold;">/</span>.bashrc</span></code>即可。</li>
<li>临时取消自定义的<code class="codecolorer bash default"><span class="bash"><span style="color: #c20cb9; font-weight: bold;">rm</span></span></code>：可以使用前文所说的<code class="codecolorer bash default"><span class="bash"><span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">rm</span></span></code>或在当前环境下取消该function的定义：<code class="codecolorer bash default"><span class="bash"><span style="color: #7a0874; font-weight: bold;">unset</span> <span style="color: #660033;">-f</span> <span style="color: #c20cb9; font-weight: bold;">rm</span></span></code>。</li>
<li>需要根据自己的系统，修改一下各个变量的定义。</li>
</blockquote>
<p><script src="https://gist.github.com/2157145.js"> </script></p>
]]></content:encoded>
			<wfw:commentRss>http://iregex.org/blog/safer-rm-command.html/feed</wfw:commentRss>
		<slash:comments>31</slash:comments>
		</item>
		<item>
		<title>饭否新手指南（非官方）</title>
		<link>http://iregex.org/blog/fanfou-the-missing-manual.html</link>
		<comments>http://iregex.org/blog/fanfou-the-missing-manual.html#comments</comments>
		<pubDate>Sat, 27 Nov 2010 08:09:15 +0000</pubDate>
		<dc:creator>rex</dc:creator>
				<category><![CDATA[杂项]]></category>
		<category><![CDATA[fanfou]]></category>

		<guid isPermaLink="false">http://iregex.org/?p=153</guid>
		<description><![CDATA[500多天之后，饭否回来了。这是不是以前的那个饭否不要紧，重要的是你还是那个你。(via@王兴) 有人说：“饭否回来不被阉割就很好了。”要俺看被阉割也成啊，被阉割俺也愿意继续跟它，好... ]]></description>
			<content:encoded><![CDATA[<p>500多天之后，饭否回来了。这是不是以前的那个饭否不要紧，重要的是你还是那个你。(via<a href="http://fanfou.com/wangxing" target="_blank">@王兴</a>) 有人说：“饭否回来不被阉割就很好了。”要俺看被阉割也成啊，被阉割俺也愿意继续跟它，好歹曾经完整过，不像这个新浪围脖儿，还没出生时就是太监了。(via <a href="http://fanfou.com/dawaiwai" target="_blank">@女流氓.exe</a>)</p>
<p>总结了一款非官方的新手指南。老fanfouers请无视。</p>
<p><span id="more-153"></span></p>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">饭否官方求助页面</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<li><a target="_blank" href="http://fanfou.com/help">http://fanfou.com/help</a></li>
<li><a target="_blank" href="http://help.fanfou.com/faq.html">http://help.fanfou.com/faq.html</a></li>
</blockquote>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">注册新帐户</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<p>现在饭否采用了邀请制注册方式。可以使用下面的邀请码：</p>
<p><a target="_blank" href="http://fanfou.com/register/cDzSYlKOY6MX">http://fanfou.com/register/cDzSYlKOY6MX</a> （<a href="http://fanfou.com/zhasm" target="_blank">@.rex</a>提供）</p>
<p>我猜测如果A提供注册链接，供B注册的话，A和B自动相互Follow。这能够解释为什么有的人的friends 和 followers 同时上升，而自己并没有主动去follow 谁的。猜测而已。求官方证实。</p>
<p>PS: 听一下<a href="http://fanfou.com/lydon" target="_blank">@带三个表</a> 的心声：“为了方便大家注册微博，我在博客上把邀请链接贴出来了。所以大家进来后默认我关注你。但是现在有将近三千人被我关注，我实在看不过来，就把不认识的人取消了。如果您将来写的好看，我还会关注。”</p>
</blockquote>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">饭否登录</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<li>电脑登录页面：</li>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<ul>
<li><a target="_blank" href="http://fanfou.com/index">http://fanfou.com/index</a></li>
<li><a target="_blank" href="http://fanfou.com/home">http://fanfou.com/home</a></li>
<li><span class='title' style='color: #127ADB; font-weight: bold; margin-right: 5px;'>官方主页：</span><a href="http://fanfou.com" title="我爱正则表达式" target="_blank">http://fanfou.com</a> 该页面目前仍是《岁月神偷》的图片。点击该图片后，就会出现登录框。</li>
</ul>
</blockquote>
<li>手机登录</li>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<ul>
<li>请访问<a target="_blank" href="http://m.fanfou.com/home">http://m.fanfou.com/home</a></li>
<li><span class='title' style='color: #127ADB; font-weight: bold; margin-right: 5px;'>iPhone</span> 版的登录地址：<a href='http://i.fanfou.com' target="_blank">http://i.fanfou.com</a>。</li>
</ul>
</blockquote>
<li>结合<a href="http://fanfou.com/moon" target="_blank">@穆荣均</a> 所说，可以使用下面的登录名：</li>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<ul>
<li>自己的短网址（即个性域名，例如<a target="_blank" href="http://fanfou.com/zhasm">http://fanfou.com/zhasm</a> ，就使用 zhasm 来登录）；大小写无关。</li>
<li>自己的邮箱</li>
<li>之前登记过的手机号</li>
</ul>
</blockquote>
</blockquote>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">发消息的正确格式</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<li><span class='title' style='color: #127ADB; font-weight: bold; margin-right: 5px;' >提及某人</span> 消息正文@用户名称 半角空格 其余消息。@号为半角。</li>
<li>@号之前可以没有空格，但是用户名称后一定要有空格才可以。最简单的办法是直接点击页面上的回复与转发。</li>
<li>@号之后是用户名称，而不是ID（或曰短网址）。这与推特的做法是截然不同的。</li>
<li><span class='title' style='color: #127ADB; font-weight: bold; margin-right: 5px;'>贴网址</span> 饭否对于网址的解析，同样比推特的更智能。一般情况下，网址前后都没有空格分隔也能正确解析。但是两端各加一个空格，是最优雅的方式，在任何微博中都通行无阻。</li>
<li><span class='title' style='color: #127ADB; font-weight: bold; margin-right: 5px;'>@与回复的关系</span>受<a href="http://fanfou.com/kndanny">@布丁丁丁</a>的委托，面向从新浪刚转至饭否的朋友，解释一下@与回复的关系。 <br />
    可能在新浪两者是没有直接关系的。在饭否，可以这样简单解释一下：如果饭否消息里有N个 @饭友名称 ，则这N位饭友都会在饭否界面 @提到我的 一栏看到通知；如果饭友A给他的好友B发了一条消息：&#8221;@B &#8230;&#8230;&#8221;，则只有既关注A又关注B的人才能在自己的主页看到这条消息。如果A发的不是以＠开头的消息，例如：&#8221;something @B &#8230;&#8230;&#8221;，则A的所有听众都会看到这条消息。一般而言，如果只是针对B发的消息，较为礼貌的格式就是&#8221;@B &#8230;&#8221;，这样既不影响B收到这条消息，又不打扰其他饭友。但愿我解释清楚了。没关系，没那么复杂。尝试一下你就知道。</li>
</blockquote>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">上传图片</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<li>电脑上传</li>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<ul>
<li><a target="_blank" href="http://m.fanfou.com/photo.upload">http://m.fanfou.com/photo.upload</a></li>
</ul>
</blockquote>
<li>手机上传</li>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<ul>
<li>下载手机拍拍1.10，手机可以访问这里<a target="_blank" href="http://m.fanfou.com/paipai">http://m.fanfou.com/paipai</a></li>
<li>或者这里：<a target="_blank" href="http://fanfou.com/paipai">http://fanfou.com/paipai</a></li>
<li>或者这里：诺基亚(s60/v3/v5)安装包直接地址<a target="_blank" href="http://static.fanfou.com/FanfouPaipai_1.10.sisx">http://static.fanfou.com/FanfouPaipai_1.10.sisx</a></li>
<li>手机拍拍是一个有口皆杯的应用。再次赞赏。</li>
<li>本人的手机绑定后大约4个小时生效。如果你的手机短时间内未绑定成功，不要着急。</li>
</ul>
</blockquote>
</blockquote>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">API以及应用</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<li><span class='title' style='color: #127ADB; font-weight: bold; margin-right: 5px;'>爱饭样式头像生成器2.0</span>地址在这里，<a href="http://avatar.ifanfou.com" title="我爱正则表达式" target="_blank">avatar.ifanfou.com</a>，非常有爱，敬请试用。 </li>
<li><span class='title' style='color: #127ADB; font-weight: bold; margin-right: 5px;'>饭否Apps</span>寻找好玩的应用<a target="_blank" href="http://help.fanfou.com/apps.html">http://help.fanfou.com/apps.html</a></li>
<li><span class='title' style='color: #127ADB; font-weight: bold; margin-right: 5px;'>饭否博客导入</span>饭否博客导入是把博客上新发表的文章自动导入到饭否的工具。当你的博客新发表一篇文章，饭否博客导入会帮你自动发布一条消息到饭否。<a target="_blank" href="http://daoru.fanfou.com/l">http://daoru.fanfou.com/</a></li>
<li><span class='title' style='color: #127ADB; font-weight: bold; margin-right: 5px;'>饭否 API 应用书签</span>这是饭否官方收集的，保存在delicious上的书签集合。相当之丰富。<a target="_blank" href="http://www.delicious.com/fanfou/API%E5%BA%94%E7%94%A8">饭否 API 应用书签</a></li>
<li><span class='title' style='color: #127ADB; font-weight: bold; margin-right: 5px;'>爱饭</span>这是一款非常不错的饭否客户端。因为有Adobe Air的支持，该应用可以在Windows, Linux, 以及Mac下使用。界面美观，功能贴心。</li>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<ul>
<li><a href="http://code.google.com/p/ifan/">code.google.com</a></li>
</ul>
</blockquote>
<li><span class='title' style='color: #127ADB; font-weight: bold; margin-right: 5px;'>爱饭官方</span>爱饭的作者是<a href="http://fanfou.com/realazy" target="_blank">@realazy</a> 同学，请你关注爱饭的帐号：<a href="http://fanfou.com/ifan">@ifan</a> 。</li>
<li><span class='title' style='color: #127ADB; font-weight: bold; margin-right: 5px;'>iPhone客户端</span><br />
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<ul>
<li><span class='title' style='color: #127ADB; font-weight: bold; margin-right: 5px;'><a href="http://fanfou.com/wanhuai" target="_blank">@郭万怀</a>提供的链接</span><a href="http://u.115.com/file/f8f61b85c">115.com</a>, 并提示，只能供已越狱的iPhone手机使用。App Store对上传的软件要求服务器要稳定，现在我们刚开始，服务器要调试。所以，他暂时还没有上传到App Store官方网站。如果有新消息，会在饭否里第一时间通知。如果有其它同学制作了iPhone客户端，我们也会第一时间通知大家。(via <a href="http://fanfou.com/wanhuai" target="_blank">@郭万怀</a>)
        </li>
<li><span class='title' style='color: #127ADB; font-weight: bold; margin-right: 5px;'>饭友Tiger 提供提供的链接</span><a href="http://bbs.weiphone.com/read-htm-tid-1382320.html">bbs.weiphone.com</a>没有测试。请自行尝试。</li>
</ul>
</blockquote>
<li><span class='title' style='color: #127ADB; font-weight: bold; margin-right: 5px;'>FanFox(Firefox的饭否插件)</span>饭友<a href="http://fanfou.com/ray..." title="我爱正则表达式" target="_blank">@雷小雷</a>提供的链接。在这里<a href="http://u.115.com/file/t6e58d9786" title="我爱正则表达式" target="_blank">115.com</a>。已经修正API问题。这是一款非常好用的插件，推荐以Firefox为主浏览器的朋友使用。附fanfox的官网地址<a href="http://panweizeng.com/fanfox" title="我爱正则表达式" target="_blank">panweizeng.com</a>。
    </li>
</blockquote>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">饭否公约</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<li><span class='title' style='color: #127ADB; font-weight: bold; margin-right: 5px;'>修改头像</span>建议新注册用户尽快修改一下头像，不要使用默认的问号头像。这个头像出现别人的好友表里的话，对别人不礼貌，自己也没有起到识别宣传的作用。而且，即使是被人加为好友，也有可能被清理掉。</li>
<li><span class='title' style='color: #127ADB; font-weight: bold; margin-right: 5px;'>修改ID</span> ID就是你的短域名。相比与上一项，这个不是必需修改的，而且只有修改一次的机会。想好了再改。</li>
<li><span class='title' style='color: #127ADB; font-weight: bold; margin-right: 5px;'>个人介绍</span>个人介绍是你在饭否的开场白，是你准备向其它饭友介绍一个怎样的自己，是其他饭友决定follow你与否的重要参考。因此，花点心思好好介绍一下自己，可能会迅速赢得不少关注。</li>
<li><span class='title' style='color: #127ADB; font-weight: bold; margin-right: 5px;'>尽量不版聊</span>这个只是提一个建议。视你自己的习惯，以及你的好友对你的容忍度而定。如果你在话痨圈，这个约定就很宽松；如果你的好友都有time line洁癖，喋喋不休的人会被unfo 或 block。</li>
<li><span class='title' style='color: #127ADB; font-weight: bold; margin-right: 5px;'>加删随意</span>你有follow别人的权利（私密型除外），但是对方没有follow back的义务。多分享一些有趣有用的话题，自然会吸引更多的人follow你。</li>
</blockquote>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">导航</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<li><span class='title' style='color: #127ADB; font-weight: bold; margin-right: 5px;'>排行榜</span>大牛们聚集的地方。你如果初来乍到，不知道应该follow谁，那么不妨来这里看看，或许能找到不少。<a target="_blank" href="http://bang.fanfou.com/">http://bang.fanfou.com/</a>。“有的人很重要，你一定要follow；有的人更重要，你不必follow，自会有人将他的话转发给你。”(via<a href="http://fanfou.com/%E5%92%8C%E8%8F%9C%E5%A4%B4" target="_blank">@和菜头</a> )<br/><br />
    另外，你也可以给自己加上标签（最多三个）。</li>
<li><span class='title' style='color: #127ADB; font-weight: bold; margin-right: 5px;'>可能关注的人</span>貌似是根据你现在follow的用户群，帮你推荐一些新朋友。与“豆瓣猜”类似。<a target="_blank" href="http://fanfou.com/userpush">http://fanfou.com/userpush</a></li>
<li><span class='title' style='color: #127ADB; font-weight: bold; margin-right: 5px;'>小调查</span><a target="_blank" href="http://spreadsheets.google.com/viewform?formkey=dHp4ZlhOWlQ3bml0QjZFZU9nYWplUXc6MQ">饭否新增功能需求小调查</a>。参与一下吧，让饭否更好用～</li>
</blockquote>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">饭否的新特性</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<li><span class='title' style='color: #127ADB; font-weight: bold; margin-right: 5px;'>标签</span>使用两个半角井号 ## 将中文或英文词包围起来即可。例如，#fanofu# #应用#. 将来服务器布署完毕之后，可以通过http://fanfou.com/q/TAG_KEYWORD 的方式访问该标签下的消息集后。</li>
<li><span class='title' style='color: #127ADB; font-weight: bold; margin-right: 5px;'>压缩网址: ye.ma</span> 消息中的长网址自动被压缩为ye.ma短网址 。这是自动进行的，但是却不够智能。原因是在你输入长网址时，你只能输入 140-length(长网址) 的字数，而不是 140-length(短网址) 个字。解决办法是不用它，先使用id.gd等压缩好了，再来输入。如果你需要的话。不过，无论使用何种压缩网址，都可以方便转发。
    </li>
<li><span class='title' style='color: #127ADB; font-weight: bold; margin-right: 5px;'>logo</span>加上了“测试版”。</li>
</blockquote>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">问答(结合饭否金牌客户<a href="http://fanfou.com/wanhuai" target="_blank">@郭万怀</a>的留言整理; 文中的“我们”指饭否官方)</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<li><span class='title' style='color: #127ADB; font-weight: bold; margin-right: 5px;'>为什么饭否关闭期间有人可以一直更新饭否消息?</span><br />
    在此期间其实仍然可以使用发短信至13489133650的方式锲而不舍地更新自己的状态。</li>
<li><span class='title' style='color: #127ADB; font-weight: bold; margin-right: 5px;'>为什么收不到验证邮箱？</span>非常抱歉，因为饭否这几天来的人超多，服务器无法一下子发完那么多邮件，存在严重延迟和丢失的现象。我们的工程师正在努力解决，希望本周内有所改善，让你收到验证邮箱的电子邮件。
    </li>
<li><span class='title' style='color: #127ADB; font-weight: bold; margin-right: 5px;'>api什么时候开放？</span>对不起，这是我们的错。一开始没有预料到会有那么多人回来，以为最多就是二、三十万的样子。刚开始内测，服务器就被压垮了。经过工程师的紧急处理，目前可以保证网页访问，消灭白屏现象。我们希望在本周（11月末～12月初）晚些时候能够开放API服务，祈祷别把服务器又拉垮了。 </li>
<li><span class='title' style='color: #127ADB; font-weight: bold; margin-right: 5px;'>首页新关注我的用户列表怎么不见了？</span>由于系统压力，之前暂时关闭了这个功能，今天（11月29日）已恢复正常。</li>
</blockquote>
<p><br/></p>
<p>如果您想到其它，请补充。谢谢。<span class='title' style='color: #127ADB; font-weight: bold; margin-right: 5px;'>本文持续更新中。</span></p>
]]></content:encoded>
			<wfw:commentRss>http://iregex.org/blog/fanfou-the-missing-manual.html/feed</wfw:commentRss>
		<slash:comments>30</slash:comments>
		</item>
		<item>
		<title>搞定Mac下的郑码输入法</title>
		<link>http://iregex.org/blog/zhengma-on-openvanilla-for-mac.html</link>
		<comments>http://iregex.org/blog/zhengma-on-openvanilla-for-mac.html#comments</comments>
		<pubDate>Sun, 07 Nov 2010 14:43:05 +0000</pubDate>
		<dc:creator>rex</dc:creator>
				<category><![CDATA[应用]]></category>
		<category><![CDATA[ime]]></category>
		<category><![CDATA[openvanilla]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[zhengma]]></category>

		<guid isPermaLink="false">http://iregex.org/?p=152</guid>
		<description><![CDATA[最近用上了Mac, 苦于没有一份好用的郑码输入法. 于是发挥不怕折腾的精神, 自己制作一份码表, 记在这里. 郑码 估计没多少人使用郑码吧, 这是一个非常小众的输入法方案, 与五笔类似, 据说更&#8... ]]></description>
			<content:encoded><![CDATA[<p>最近用上了Mac, 苦于没有一份好用的郑码输入法. 于是发挥不怕折腾的精神, 自己制作一份码表, 记在这里. </p>
<p> <span id="more-152"></span></p>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">郑码</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<p>估计没多少人使用<a href="http://zh.wikipedia.org/zh/%E9%83%91%E7%A0%81%E8%BE%93%E5%85%A5%E6%B3%95">郑码</a>吧, 这是一个非常小众的输入法方案, 与五笔类似, 据说更&#8221;规则&#8221;. 没有用过五笔, 不好评价. 个人比较喜欢, 一直在用. 无论如何, 拼音输入法是无福消受的. </p>
<p>在Ubuntu下可以使用 ibus, 但是在Mac下就没有这么幸运了. Fit是不错的输入法, 但是只有内置的拼音和五笔, 暂不支持自定义码表; QIM是收费软件, 貌似可以自定义码表, 但它缺少文档, 找了半天没发现多少有用信息. </p>
<p>搜索一番, 找到一个OpenVanilla, 香草输入法. 免费, 开放, 支持自定义码表. 地址在<a href="http://openvanilla.org/">这里</a> . 另外从郑码爱好者家园上看到一个类似的解决方案, 只不过不太完美(例如, 无法忍受的词频混乱问题). 地址在<a href="http://www.cn25.net/zm/showbbs.asp?bd=14&#038;id=841&#038;totable=1">这里</a>  . </p>
</blockquote>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">做一份郑码码表</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<p><strong>词汇列表:</strong> 使用的是搜狗实验室的语料文本. 地址在<a href="http://www.sogou.com/labs/dl/w.html">这里</a>  , 格式为 &#8220;词A 词频 词性1 词性2 … 词性N&#8221;, 取自己有用的词汇以及对应词频信息即可. 该文件只有两字词至多字词, 没有单个汉字的字频信息. </p>
<p><strong>字频列表:</strong> 在 <a href="http://lingua.mtsu.edu/chinese-computing/statistics/">lingua.mtsu.edu</a> 上找到了字频列表, 令人喜出望外的是, 它还带有单字的(多音字)拼音/声调. 这为我打造一份带有拼音辅助的码表方案提供了极大的便利. 其实拼音只作为形码的辅助而使用, 只有打不出的字才反查拼音, 无需单字或词汇的简拼信息. 又因为它是辅助, 因此将所有的拼音信息放在做好的列表的末尾即可. </p>
<p>有了上述的两个文件, 就可以准备做码表了. 不过, 还需要单字的构词码码表, 以及约定俗成的快速码表(例如, 对于&#8221;北京&#8221;一词, 郑码有两种打法, 一是简单的ts, 一是正规的trsj). 单字构词码表之前我已经准备出来了, 后者我从网上搜索到的郑码光盘中找到了大字集的码表.</p>
<p>制作的过程不难, 不过细节不少. 不赘述. 过程中当然少不了<a href="http://iregex.org">正则表达式</a>的帮忙.</p>
<p>最终做出来的是五码郑码. 非常好用. 每次启动香草时要花一秒钟左右的时间, 但是一旦运行起来, 就感觉不到了. 毕竟, 最终的词汇列表为19万条之巨.</p>
<p>香草的最大的优势在于开放和免费. 比起qim或fit来, 它作为一个输入法, 支持的特性/自定义功能实在有限. 连自定义切换中英文也不可以, 更不用说动态调整词频和增删词条了. 我写了一个bash function, 用来搜索现有的词条; 写了一个bash脚本, 用来删除词条; 写了一个python程序, 用来动态添加新词.</p>
<p>最后这个添加新词的python程序还是比较好玩的. 支持从命令行中或文件中读取词汇列表, 批量添加到词库中. 添加过程中它自己生成格式正确的郑码编码; 添加完毕之后还会杀死香草, 以便重新加载新词库. </p>
<p>程序push到github了. 在<a href="https://github.com/zhasm/zhengma">这里</a>. </p>
</blockquote>
<p><a href="http://iregex.org/blog/zhengma-on-openvanilla-for-mac.html" target="_blank"><img src="http://i293.photobucket.com/albums/mm60/zhasm/iregex/Screenshot2010-11-07at103904PM.png" border="0" alt="Photobucket"></a></p>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">Update</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<li><strong>2010-11-08</strong>查看了一下香草的其它输入法码表，搞定了标点符号。 </li>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://iregex.org/blog/zhengma-on-openvanilla-for-mac.html/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>一个简单的中文分词程序</title>
		<link>http://iregex.org/blog/simple-nlp-for-chinese.html</link>
		<comments>http://iregex.org/blog/simple-nlp-for-chinese.html#comments</comments>
		<pubDate>Sun, 26 Sep 2010 14:41:12 +0000</pubDate>
		<dc:creator>rex</dc:creator>
				<category><![CDATA[应用]]></category>
		<category><![CDATA[chinese]]></category>
		<category><![CDATA[nlp]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[utf8]]></category>

		<guid isPermaLink="false">http://iregex.org/?p=151</guid>
		<description><![CDATA[kds:“前驻法大使吴建民指出，应该理**国”,想了一下，原来两个星号是“性爱”两字，生活在一个机械屏蔽时代的中国还真有喜感。——via 想必您也看到了推特上关于“理＊＊国”的笑话了。... ]]></description>
			<content:encoded><![CDATA[<blockquote  style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;"><p>
    kds:“前驻法大使吴建民指出，应该理**国”,想了一下，原来两个星号是“性爱”两字，生活在一个机械屏蔽时代的中国还真有喜感。——<a href="https://twitter.com/rightf/status/25555437368" title="我爱正则表达式" target="_blank">via</a>
</p></blockquote>
<p>想必您也看到了推特上关于“<a href="https://twitter.com/rex_zhasm/status/25567030862" title="我爱正则表达式" target="_blank">理＊＊国</a>”的笑话了。我正好想学一下中文分词方面的知识，这是第一篇。</p>
<p><span id="more-151"></span></p>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">分词原理与实现</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<p>英语等以空白字符作为分隔符的语言，分词不是问题。中文分词，需要处理的细节太多。单就“<a href="http://is.gd/ftZNO" title="我爱正则表达式" target="_blank">真歧义</a>”这一问题（简言之，如果没有上下文，连活生生的人也无法确定如何断句的歧义句）的处理方法而言，前辈们就已写出洋洋洒洒许多文字。不过这属于进阶题目。我想先实现一个最简单的分词程序。</p>
<p>以我的理解，最简单的分词程序，应该是先将中文文本切成最小的单位－－汉字－－再从词典里找词，将这些字按照最左最长原则（与正则精神暗合），合并为以词为单位的集合。这样的应该是最快的，只按照给定的数据划分合并即可，不必考虑语法元素的权重（词性：名动形数量代等等，语法：主谓宾定状补），以及上下文的出现次数。</p>
<p>关于源文本的切分，就参照<a href="http://iregex.org/blog/words-counter-in-python.html" title="我爱正则表达式" target="_blank">《统计汉字／英文单词数》</a>一文的思路，使用正则表达式<code class="codecolorer python default"><span class="python">r<span style="color: #483d8b;">&quot;(?x) (?: [<span style="color: #000099; font-weight: bold;">\w</span>-]+ &nbsp;| [<span style="color: #000099; font-weight: bold;">\x</span>80-<span style="color: #000099; font-weight: bold;">\x</span>ff]{3} )&quot;</span><span style="color: black;">&#41;</span></span></code>来匹配即可。</p>
<p>关于词典，我使用的是<a href="http://www.mdbg.net/chindict/chindict.php?page=cedict" title="我爱正则表达式" target="_blank">CC-CEDICT</a>的词典，原因有三：没有版权问题；速度较快；Chrome也在用它（发现了吧：在Chrome上双击中文句子，会自动选择中文词汇而不是单字或整行进行反选高亮）。</p>
<p>接下来是如何分词。经过思考，我发现搜索树的原理可以拿来就用。原理请见此文：<a href="http://iregex.org/blog/trie-in-python.html" title="我爱正则表达式" target="_blank">Trie in Python</a>。具体方法是，将词库逐字读入内存，建立搜索树；然后对目标文本进行逐字分析，如果该字之后还可搜索，则继续搜索；否则停止，作为一个词汇单位处理。</p>
<p>这样的算法理论上比较快（未进行benchmark），原因有三：使用Trie结构，本质上是哈希表，空间换时间，是O(0)级的搜索；词库只有800K，可以轻易载入，内存空间没占多少；算法最慢的部分是载入Trie的阶段，之后速度就不再受影响。</p>
<p>不过，谈到它的扩充性，目前只能在words.txt中手动添加新词，而不能实现机器学习。</p>
</blockquote>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">源码</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<p>完整的程序（包括我处理过的词库列表）放在<a href="http://github.com/zhasm/simpleNLP" title="我爱正则表达式" target="_blank">github</a>上了。有兴趣的可以把玩一下。这里列出主程序：</p>
<div class="codecolorer-container python mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">#!/usr/bin/python</span><br />
<span style="color: #808080; font-style: italic;"># -*- coding: utf-8 -*-</span><br />
<span style="color: #808080; font-style: italic;">#</span><br />
<span style="color: #808080; font-style: italic;">#author: &nbsp; &nbsp; &nbsp; &nbsp; rex</span><br />
<span style="color: #808080; font-style: italic;">#blog: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; http://iregex.org</span><br />
<span style="color: #808080; font-style: italic;">#filename &nbsp; &nbsp; &nbsp; &nbsp;nlp.py</span><br />
<span style="color: #808080; font-style: italic;">#created: &nbsp; &nbsp; &nbsp; &nbsp;2010-09-26 19:15</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">re</span><br />
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span><br />
<br />
regex<span style="color: #66cc66;">=</span><span style="color: #dc143c;">re</span>.<span style="color: #008000;">compile</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">&quot;(?x) (?: [<span style="color: #000099; font-weight: bold;">\w</span>-]+ &nbsp;| [<span style="color: #000099; font-weight: bold;">\x</span>80-<span style="color: #000099; font-weight: bold;">\x</span>ff]{3} )&quot;</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> init_wordslist<span style="color: black;">&#40;</span>fn<span style="color: #66cc66;">=</span><span style="color: #483d8b;">&quot;./words.txt&quot;</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; f<span style="color: #66cc66;">=</span><span style="color: #008000;">open</span><span style="color: black;">&#40;</span>fn<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; lines<span style="color: #66cc66;">=</span><span style="color: #008000;">sorted</span><span style="color: black;">&#40;</span>f.<span style="color: black;">readlines</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; f.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> lines<br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> words_2_trie<span style="color: black;">&#40;</span>wordslist<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; d<span style="color: #66cc66;">=</span><span style="color: black;">&#123;</span><span style="color: black;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> word <span style="color: #ff7700;font-weight:bold;">in</span> wordslist: <br />
&nbsp; &nbsp; &nbsp; &nbsp; ref<span style="color: #66cc66;">=</span>d<br />
&nbsp; &nbsp; &nbsp; &nbsp; chars<span style="color: #66cc66;">=</span>regex.<span style="color: black;">findall</span><span style="color: black;">&#40;</span>word<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> char <span style="color: #ff7700;font-weight:bold;">in</span> chars:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ref<span style="color: black;">&#91;</span>char<span style="color: black;">&#93;</span><span style="color: #66cc66;">=</span>ref.<span style="color: black;">has_key</span><span style="color: black;">&#40;</span>char<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">and</span> ref<span style="color: black;">&#91;</span>char<span style="color: black;">&#93;</span> <span style="color: #ff7700;font-weight:bold;">or</span> <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ref<span style="color: #66cc66;">=</span>ref<span style="color: black;">&#91;</span>char<span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; ref<span style="color: black;">&#91;</span><span style="color: #483d8b;">''</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> d<br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> search_in_trie<span style="color: black;">&#40;</span>chars<span style="color: #66cc66;">,</span> trie<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; ref<span style="color: #66cc66;">=</span>trie<br />
&nbsp; &nbsp; index<span style="color: #66cc66;">=</span><span style="color: #ff4500;">0</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> char <span style="color: #ff7700;font-weight:bold;">in</span> chars:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> ref.<span style="color: black;">has_key</span><span style="color: black;">&#40;</span>char<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> char<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ref<span style="color: #66cc66;">=</span>ref<span style="color: black;">&#91;</span>char<span style="color: black;">&#93;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; index+<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> index<span style="color: #66cc66;">==</span><span style="color: #ff4500;">0</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; index<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> char<span style="color: #66cc66;">,</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'*'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">try</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; chars<span style="color: #66cc66;">=</span>chars<span style="color: black;">&#91;</span>index:<span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; search_in_trie<span style="color: black;">&#40;</span>chars<span style="color: #66cc66;">,</span> trie<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">except</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">pass</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">break</span><br />
<span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">#init</span><br />
&nbsp; &nbsp; words<span style="color: #66cc66;">=</span>init_wordslist<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; trie<span style="color: #66cc66;">=</span>words_2_trie<span style="color: black;">&#40;</span>words<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">#read content</span><br />
&nbsp; &nbsp; fn<span style="color: #66cc66;">=</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; <span style="color: #dc143c;">string</span><span style="color: #66cc66;">=</span><span style="color: #008000;">open</span><span style="color: black;">&#40;</span>fn<span style="color: black;">&#41;</span>.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; chars<span style="color: #66cc66;">=</span>regex.<span style="color: black;">findall</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">string</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">#do the job</span><br />
&nbsp; &nbsp; search_in_trie<span style="color: black;">&#40;</span>chars<span style="color: #66cc66;">,</span> trie<span style="color: black;">&#41;</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">if</span> __name__<span style="color: #66cc66;">==</span><span style="color: #483d8b;">'__main__'</span>:<br />
&nbsp; &nbsp; main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
</blockquote>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">本机测试</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<p>测试的文本如下：</p>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">只听得一个女子低低应了一声。绿竹翁道：“姑姑请看，这部琴谱可有些古怪。”那<br />
女子又嗯了一声，琴音响起，调了调弦，停了一会，似是在将断了的琴弦换去，又调了调<br />
弦，便奏了起来。初时所奏和绿竹翁相同，到后来越转越高，那琴韵竟然履险如夷，举重<br />
若轻，毫不费力的便转了上去。令狐冲又惊又喜，依稀记得便是那天晚上所听到曲洋所奏<br />
的琴韵。这一曲时而慷慨激昂，时而温柔雅致，令狐冲虽不明乐理，但觉这位婆婆所奏，<br />
和曲洋所奏的曲调虽同，意趣却大有差别。这婆婆所奏的曲调平和中正，令人听着只觉音<br />
乐之美，却无曲洋所奏热血如沸的激奋。奏了良久，琴韵渐缓，似乎乐音在不住远去，倒<br />
像奏琴之人走出了数十丈之遥，又走到数里之外，细微几不可再闻。<br />
<br />
理性爱国<br />
性爱体验<br />
我爱正则表达式</div></td></tr></tbody></table></div>
<p>请留意末尾三行。</p>
<p>再看一下程序处理的结果：（＊表示词汇间的分隔）</p>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">只 * 听 得 * 一 个 * 女 子 * 低 低 * 应 * 了 * 一 声 * 。 * 绿 * 竹 * 翁 * 道 * ： * “ * 姑 姑 * 请 看 * ， * 这 * 部 * 琴 * 谱 * 可 有 * 些 * 古 怪 * 。 * ” * 那 * 女 子 * 又 * 嗯 * 了 * 一 声 * ， * 琴 * 音 响 * 起 * ， * 调 * 了 * 调 * 弦 * ， * 停 * 了 * 一 会 * ， * 似 是 * 在 * 将 * 断 * 了 * 的 * 琴 弦 * 换 * 去 * ， * 又 * 调 * 了 * 调 * 弦 * ， * 便 * 奏 * 了 * 起 来 * 。 * 初 * 时 * 所 * 奏 * 和 * 绿 * 竹 * 翁 * 相 同 * ， * 到 * 后 来 * 越 * 转 * 越 * 高 * ， * 那 * 琴 * 韵 * 竟 然 * 履 险 如 夷 * ， * 举 重 * 若 * 轻 * ， * 毫 不 费 力 * 的 * 便 * 转 * 了 * 上 去 * 。 * 令 狐 * 冲 * 又 * 惊 * 又 * 喜 * ， * 依 稀 * 记 得 * 便 是 * 那 天 * 晚 上 * 所 * 听 到 * 曲 * 洋 * 所 * 奏 * 的 * 琴 * 韵 * 。 * 这 一 * 曲 * 时 而 * 慷 慨 * 激 昂 * ， * 时 而 * 温 柔 * 雅 致 * ， * 令 狐 * 冲 * 虽 * 不 明 * 乐 理 * ， * 但 * 觉 * 这 位 * 婆 婆 * 所 * 奏 * ， * 和 * 曲 * 洋 * 所 * 奏 * 的 * 曲 调 * 虽 * 同 * ， * 意 趣 * 却 * 大 有 * 差 别 * 。 * 这 * 婆 婆 * 所 * 奏 * 的 * 曲 调 * 平 和 * 中 正 * ， * 令 人 * 听 * 着 * 只 * 觉 * 音 乐 之 * 美 * ， * 却 * 无 * 曲 * 洋 * 所 * 奏 * 热 血 * 如 * 沸 * 的 * 激 * 奋 * 。 * 奏 * 了 * 良 久 * ， * 琴 * 韵 * 渐 * 缓 * ， * 似 乎 * 乐 音 * 在 * 不 住 * 远 * 去 * ， * 倒 像 * 奏 * 琴 * 之 * 人 * 走 出 * 了 * 数 十 * 丈 * 之 * 遥 * ， * 又 * 走 * 到 * 数 * 里 * 之 外 * ， * 细 微 * 几 * 不 可 再 * 闻 * 。 * 理 性 * 爱 国 * 性 爱 * 体 验 * 我 * 爱 * 正 则 * 表 达 式</div></td></tr></tbody></table></div>
</blockquote>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">更新</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<p><strong>2010-10-03更新</strong>:发现本程序的一个bug。已改进算法，更精确，更快速。程序详见GitHub，链接如前。</p>
<p>请看新程序的分词结果：</p>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<p>只 * 听 * 得 * 一 * 个 * 女子 * 低 * 低 * 应 * 了 * 一声 * 。 * 绿 * 竹 * 翁 * 道 * ： * “ * 姑姑 * 请看 * ， * 这 * 部 * 琴谱 * 可 * 有些 * 古怪 * 。 * ” * 那 * 女子 * 又 * 嗯 * 了 * 一声 * ， * 琴 * 音响 * 起 * ， * 调 * 了 * 调 * 弦 * ， * 停 * 了 * 一会 * ， * 似 * 是 * 在 * 将 * 断 * 了 * 的 * 琴弦 * 换 * 去 * ， * 又 * 调 * 了 * 调 * 弦 * ， * 便 * 奏 * 了 * 起来 * 。 * 初 * 时 * 所 * 奏 * 和 * 绿 * 竹 * 翁 * 相同 * ， * 到 * 后来 * 越 * 转 * 越 * 高 * ， * 那 * 琴 * 韵 * 竟然 * 履 * 险 * 如 * 夷 * ， * 举重 * 若 * 轻 * ， * 毫不 * 费力 * 的 * 便 * 转 * 了 * 上去 * 。 * 令狐 * 冲 * 又 * 惊 * 又 * 喜 * ， * 依稀 * 记得 * 便是 * 那天 * 晚上 * 所 * 听到 * 曲 * 洋 * 所 * 奏 * 的 * 琴 * 韵 * 。 * 这 * 一 * 曲 * 时而 * 慷慨 * 激昂 * ， * 时而 * 温柔 * 雅致 * ， * 令狐 * 冲 * 虽 * 不明 * 乐理 * ， * 但 * 觉 * 这位 * 婆婆 * 所 * 奏 * ， * 和 * 曲 * 洋 * 所 * 奏 * 的 * 曲调 * 虽 * 同 * ， * 意趣 * 却 * 大有 * 差别 * 。 * 这 * 婆婆 * 所 * 奏 * 的 * 曲调 * 平和 * 中正 * ， * 令人 * 听 * 着 * 只 * 觉 * 音乐 * 之 * 美 * ， * 却 * 无 * 曲 * 洋 * 所 * 奏 * 热血 * 如 * 沸 * 的 * 激 * 奋 * 。 * 奏 * 了 * 良久 * ， * 琴 * 韵 * 渐 * 缓 * ， * 似乎 * 乐音 * 在 * 不住 * 远 * 去 * ， * 倒像 * 奏 * 琴 * 之 * 人 * 走出 * 了 * 数 * 十 * 丈 * 之 * 遥 * ， * 又 * 走 * 到 * 数 * 里 * 之外 * ， * 细微 * 几 * 不可 * 再 * 闻 * 。 *</p>
<p>理性 * 爱国 *</p>
<p>性爱 * 体验 *</p>
<p>我 * 爱 * 正则 * 表达式 *</p>
<p>轻 * 音乐 *</p>
</blockquote>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://iregex.org/blog/simple-nlp-for-chinese.html/feed</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>统计汉字／英文单词数</title>
		<link>http://iregex.org/blog/words-counter-in-python.html</link>
		<comments>http://iregex.org/blog/words-counter-in-python.html#comments</comments>
		<pubDate>Sat, 25 Sep 2010 11:25:38 +0000</pubDate>
		<dc:creator>rex</dc:creator>
				<category><![CDATA[应用]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://iregex.org/?p=148</guid>
		<description><![CDATA[一个简单的程序，统计文本文档中的单词和汉字数，逆序排列（出现频率高的排在最前面）。python实现。 思路 使用正则式 &#34;(?x) (?: [\w-]+ &#160;&#124; [\x80-\xff]{3} )&#34;获得utf-8文档中的英文单词... ]]></description>
			<content:encoded><![CDATA[<p>一个简单的程序，统计文本文档中的单词和汉字数，逆序排列（出现频率高的排在最前面）。python实现。</p>
<p><span id="more-148"></span></p>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">思路</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<ul>
<li>使用正则式 <code class="codecolorer python default"><span class="python"><span style="color: #483d8b;">&quot;(?x) (?: [<span style="color: #000099; font-weight: bold;">\w</span>-]+ &nbsp;| [<span style="color: #000099; font-weight: bold;">\x</span>80-<span style="color: #000099; font-weight: bold;">\x</span>ff]{3} )&quot;</span></span></code>获得utf-8文档中的英文单词和汉字的列表。
            </li>
<li>使用dictionary来记录每个单词／汉字出现的频率，如果出现过则＋1，如果没出现则置1。</li>
<li>将dictionary按照value排序，输出。</li>
</ul>
</blockquote>
</blockquote>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">源码</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<div class="codecolorer-container python mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">#!/usr/bin/python</span><br />
<span style="color: #808080; font-style: italic;"># -*- coding: utf-8 -*-</span><br />
<span style="color: #808080; font-style: italic;">#</span><br />
<span style="color: #808080; font-style: italic;">#author: &nbsp; &nbsp; &nbsp; &nbsp; rex</span><br />
<span style="color: #808080; font-style: italic;">#blog: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; http://iregex.org</span><br />
<span style="color: #808080; font-style: italic;">#filename &nbsp; &nbsp; &nbsp; &nbsp;counter.py</span><br />
<span style="color: #808080; font-style: italic;">#created: &nbsp; &nbsp; &nbsp; &nbsp;Mon Sep 20 21:00:52 2010</span><br />
<span style="color: #808080; font-style: italic;">#desc: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; convert .py file to html with VIM.</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span><br />
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">re</span><br />
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">operator</span> <span style="color: #ff7700;font-weight:bold;">import</span> itemgetter<br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> readfile<span style="color: black;">&#40;</span>f<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">with</span> <span style="color: #008000;">file</span><span style="color: black;">&#40;</span>f<span style="color: #66cc66;">,</span><span style="color: #483d8b;">&quot;r&quot;</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">as</span> pFile:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> pFile.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
<span style="color: #ff7700;font-weight:bold;">def</span> divide<span style="color: black;">&#40;</span>c<span style="color: #66cc66;">,</span> regex<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">#the regex below is only valid for utf8 coding</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> regex.<span style="color: black;">findall</span><span style="color: black;">&#40;</span>c<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> update_dict<span style="color: black;">&#40;</span>di<span style="color: #66cc66;">,</span>li<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> li:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> di.<span style="color: black;">has_key</span><span style="color: black;">&#40;</span>i<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; di<span style="color: black;">&#91;</span>i<span style="color: black;">&#93;</span>+<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; di<span style="color: black;">&#91;</span>i<span style="color: black;">&#93;</span><span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> di<br />
&nbsp; &nbsp; <br />
<span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:<br />
<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">#receive files from bash</span><br />
&nbsp; &nbsp; files<span style="color: #66cc66;">=</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span>:<span style="color: black;">&#93;</span> <br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">#regex compile only once</span><br />
&nbsp; &nbsp; regex<span style="color: #66cc66;">=</span><span style="color: #dc143c;">re</span>.<span style="color: #008000;">compile</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;(?x) (?: [<span style="color: #000099; font-weight: bold;">\w</span>-]+ &nbsp;| [<span style="color: #000099; font-weight: bold;">\x</span>80-<span style="color: #000099; font-weight: bold;">\x</span>ff]{3} )&quot;</span><span style="color: black;">&#41;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #008000;">dict</span><span style="color: #66cc66;">=</span><span style="color: black;">&#123;</span><span style="color: black;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">#get all words from files</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> f <span style="color: #ff7700;font-weight:bold;">in</span> files:<br />
&nbsp; &nbsp; &nbsp; &nbsp; words<span style="color: #66cc66;">=</span>divide<span style="color: black;">&#40;</span>readfile<span style="color: black;">&#40;</span>f<span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> regex<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">dict</span><span style="color: #66cc66;">=</span>update_dict<span style="color: black;">&#40;</span><span style="color: #008000;">dict</span><span style="color: #66cc66;">,</span> words<span style="color: black;">&#41;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">#sort dictionary by value </span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">#dict is now a list.</span><br />
&nbsp; &nbsp; <span style="color: #008000;">dict</span><span style="color: #66cc66;">=</span><span style="color: #008000;">sorted</span><span style="color: black;">&#40;</span><span style="color: #008000;">dict</span>.<span style="color: black;">items</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> key<span style="color: #66cc66;">=</span>itemgetter<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> reverse<span style="color: #66cc66;">=</span><span style="color: #008000;">True</span><span style="color: black;">&#41;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">#output to standard-output</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">dict</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> i<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span> i<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span> <br />
<br />
<br />
<span style="color: #ff7700;font-weight:bold;">if</span> __name__<span style="color: #66cc66;">==</span><span style="color: #483d8b;">'__main__'</span>:<br />
&nbsp; &nbsp; main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
</blockquote>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">Tips</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<p>由于使用了<code class="codecolorer python default"><span class="python">files<span style="color: #66cc66;">=</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span>:<span style="color: black;">&#93;</span></span></code> 来接收参数，因此<code class="codecolorer bash default"><span class="bash">.<span style="color: #000000; font-weight: bold;">/</span>counter.py file1 file2 ...</span></code>可以将参数指定的文件的词频累加计算输出。 </p>
<p>可以自定义该程序。例如，</p>
<ul>
<li>使用
<div class="codecolorer-container python mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">regex<span style="color: #66cc66;">=</span><span style="color: #dc143c;">re</span>.<span style="color: #008000;">compile</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;(?x) ( [<span style="color: #000099; font-weight: bold;">\w</span>-]+ &nbsp;| [<span style="color: #000099; font-weight: bold;">\x</span>80-<span style="color: #000099; font-weight: bold;">\x</span>ff]{3} )&quot;</span><span style="color: black;">&#41;</span><br />
words<span style="color: #66cc66;">=</span><span style="color: black;">&#91;</span>w <span style="color: #ff7700;font-weight:bold;">for</span> w <span style="color: #ff7700;font-weight:bold;">in</span> regex.<span style="color: black;">split</span><span style="color: black;">&#40;</span>line<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">if</span> w<span style="color: black;">&#93;</span></div></td></tr></tbody></table></div>
<p>这样得到的列表是包含分隔符在内的单词列表，方便于以后对全文分词再做操作。
            </li>
<li>以行为单位处理文件，而不是将整个文件读入内存，在处理大文件时可以节约内存。</li>
<li>可以使用这样的正则表达式先对整个文件预处理一下，去掉可能的html tags: <code class="codecolorer python default"><span class="python">content<span style="color: #66cc66;">=</span><span style="color: #dc143c;">re</span>.<span style="color: black;">sub</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">&quot;&lt;[^&gt;]+&quot;</span><span style="color: #66cc66;">,</span><span style="color: #483d8b;">&quot;&quot;</span><span style="color: #66cc66;">,</span>content<span style="color: black;">&#41;</span></span></code>，这样的结果对于某些文档更精确。
            </li>
</ul>
</blockquote>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://iregex.org/blog/words-counter-in-python.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>正则书评</title>
		<link>http://iregex.org/blog/regex-books.html</link>
		<comments>http://iregex.org/blog/regex-books.html#comments</comments>
		<pubDate>Thu, 16 Sep 2010 16:51:28 +0000</pubDate>
		<dc:creator>rex</dc:creator>
				<category><![CDATA[书籍]]></category>

		<guid isPermaLink="false">http://iregex.org/?p=147</guid>
		<description><![CDATA[简要评价一下本人读过的几本与正则表达式有关的书。个人之见，仅供参考。 网文 vs 书藉 只要是知道“正则”这个词的，上网搜集个把资料，应该就不是问题吧。我获得正则消息的网絡渠道... ]]></description>
			<content:encoded><![CDATA[<p>简要评价一下本人读过的几本与正则表达式有关的书。个人之见，仅供参考。<span id="more-147"></span></p>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">网文 vs 书藉</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<p>只要是知道“正则”这个词的，上网搜集个把资料，应该就不是问题吧。我获得正则消息的网絡渠道有这样几个，以质量从高到低排序：dilicious标签（颇有些不错的文章） > 一些与正则相关的博客（可以参考我整理的这个页面<a href="http://iregex.org/links" title="我爱正则表达式" target="_blank">正则链接</a> ，不定期更新中） > google alerts （关键词[regex, regular expressions, 正则，正则表达式]都建议添加，有时也能发现好文章）。</p>
<p>网文资料有几大特点是实体书（简称书）无法比拟的。快速（最鲜活的一手资料），便捷（即时迅速的发布），成本低（只需花费时间成本来搜索、收集这些内容即可，总体上无需支付其它费用），零星信息多，发布网文门槛低，与作者互动容易，作者活生生的感受，网絡语言的应用，等等等等，都是实体书难以望其项背的。然而书仍未迅速消亡，原因有：符合绝大多数人的阅读习惯，是获取知识的最传统的渠道。最重要的是，作为一本书书，其系统性、严谨性，是远非一篇篇零散的博客文章所能比拟的。谁都能写博客，但是未必能写书。写书的门槛其实也自动过滤了一些芸花一现、不成体系的内容。当然，两者的目的都是为了记录知识，传播知识，殊途同归而已，在现阶段可以不必考虑谁灭谁，而应该结合起来，相互补充，为读者所用。</p>
<p>下面浅谈一下关于正则表达式的书藉。以我读的先后顺序排列。
</p></blockquote>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">Perl 语言编程</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<p>《Perl 语言编程》我首先接触的与正则式相关的书，是何伟平老师翻译的大骆驼书。书中关于 Perl 正则的篇幅不少，第五章，近百页内容全是讲正则，系统全面（包括搜索，替换，分隔，各种操作；各种元字符；各种 flag，各种零宽断言，Unicode，……），深入（匹配、回溯原理，以及最左最长原则等即6条规则——“六脉神剑”）。如果想学习 以Perl 为主的语言的正则的话，这本书中这一部分不可不读。当然，很少有 Perl 程序员没听过正则、没听过大骆驼书的。因此我这里的推荐或许是多余的。既然是 Perl only 的书，如果您对 Perl 的语法不感兴趣的话，这本书很可能不适合您。补充一下，这本书网上有个800k左右的chm电子版，但是从篇幅上看，貌似被广电总局处理过。</p>
<p>一句话书评：不适合当作新手入门材料，适合给 Perl 程序员作系统阅读和参考。</p>
<p>适合读者：中、高。</p>
</blockquote>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">精通正则表达式</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<p>《精通正则表达式》。简称MRE。这本书堪称正则界的bible。其它任何一本严肃一点的涉及正则表达的书，都会这样说一句：“本书无意剖析正则表达式的原理。如果想深刻理解正则表达式，请阅读MRE.” 这样一写，暗示了关于正则表达式的书可以分为两类，一类是 像 thinking in C++ 这样的阐述内功心法的理论性著作，另一类像是 JavaScript Cookbook 这样可以照着做、拿来就用的活生生的剑招指南。后者是便于初学者照猫画虎，立见成效；前者适合面壁参悟，结合以往的实战经验，反复阅读才能达到“十年苦修，一朝顿悟”的境界。</p>
<p>这本书不是很适合入门，虽然从开场白到前三章，都归纳了一些正则表达式的概念，但是该书的重心是四章讲述匹配引擎的工作原理，以及第五、六章的优化建议。这些理论知识与具体语言无关，内容从深度到广度，是其它正则书无法替代和超越的核心内容，是全书精华所在。其后的七至十章，介绍了一些与具体语言相关的技术和技巧，（perl/php/.net/java），也非常不错，而且也都是常用的语言的内容。相比之下，前一二三章的紧凑的开场白和暖场，就更像是从内容的完整性上考虑而添加的，作为新手来说，不能期望读完了第三章就能平滑地升级到第四章。在有了一些实际使用经验，尤其是对正则引擎的工作原理有了初步了解之后，再来读第四章，可能收获会更大。</p>
<p>书中有两句话，记忆犹新。一是读者评价：“读这本书之前，我以为自己了解正则表达式，但是现在我才真正弄明白。”就我自己而言，第四章匹配原理，我即使读了MRE也没一下子明白过来，而是中途补了编译原理的课，再回过头来攻读NFA／DFA，才豁然开朗的。</p>
<p>另一句，是关于正则表达式的作用评价的：“一旦掌握了正则表达式，你就会知道它简直是工具中的无价之宝，你也难以想象，之前那些没有正则表达式的日子是怎么度过的。” 就我自己而言，正则式的确是极其有用的工具，但是我也开始有意识地思考没有正则表达式的日子该怎么度过了。好吧，我指的是，从效率考虑，什么时候该使用正则表达式，什么时候不应该；从学习的角度出发，如何自己也写一款正则引擎，哪怕是最简单的也好。</p>
<p>一句话书评：不太适合入门，但是绝对是中手及高手的案头必备。没读过这本书的，你都不好意思跟别人说理解正则表达式。</p>
<p>适合读者：中、高。
</p></blockquote>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">《正则表达式必知必会》</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<p>最早在推特上听图灵刘江老师提到过这本书（这本书是人民邮电出的）。这是一本薄薄的小书，号称是10分钟教会你使用正则表达式，篇幅也不过150页。这样的篇幅，你不能期望它给你从头到尾讲一下匹配六原则，事实上阐述原理是其它书的职责所在。它所做的，是告诉你什么是正则表达式，应该如何使用；简明扼要的定义，加上较多的实例，的确10分钟你就学会如何匹配美国、加拿大的邮政编码了。</p>
<p>不过，不久前不是有篇极其火的《如何10年学编程》吗，总结为一句话就是要练够1万个小时才能精通；还有一篇漫画，如何21天精通C++，窍门是先花费几万天精通完所有的相关知识之后再时光旅行，杀死学c++第21天时的自己。以此来看，10分钟的教程不会让你精通正则表达式，这简直是一定的。但是，正则表达式极其有用，花个十分钟学一下，看看它大致是怎么回事，可以用来做什么，以及如何来做。之后用到正则式了，可以在原有基础之上修改，比如将上述美国、加拿大的邮政编码，替换为贵国的编码，等等。</p>
<p>我通读了一遍该书，内容还是比较丰富的。它在讲述如何使用正则表达式上，花费的力气相当大；将正则表达式按照语法特征，分为10章，逐条解释；最后用一两章的篇幅，总结如何在编程语言中使用正则，以及常见问题的固定思路。可谓麻雀虽小，五脏俱全。</p>
<p>一句话书评：适合绝对的新手入门，以及语法不太熟的中手作案头参考。</p>
<p>适合读者：初、中。</p>
<p>吹毛求疵：如果说它作为入门书还有什么缺点的话，应该是书中的不少例子都有些偏欧美风格。例如电话号码，区号什么的。虽然掌握语法之后，这些东西都是浮云。毕竟是翻译过来的书。
</p></blockquote>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">《正则表达式入门经典》</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<p>再介绍一本入门书：《正则式入门经典》，英文是《Beginning Regular Expressions》从内容上看，觉得这个中文书名比英文书名要更贴切一些。它的确是一本入门的经典著作。因为篇幅比较宽裕，它的写作方式就不像《正则表达式必知必会》那要干瘪枯燥，而是从通配字符和MS Word谈起，详细地起承转合，尽职地表现出带新人入门的耐心。从内容覆盖上来讲，它是《正则表达式必知必会》的增强版＋Office正则（MS，Excel, VBA，OOo，等等）＋Windows findstr+ PowerGREP+SQL Server+ MySQL+JavaScript+ Perl＋更多。不但是入门，还是经典的入门。</p>
<p>一句话书评：如果您只想买靠谱的“一册在手、全程无忧”的正则表达式教材的话，就是它了。</p>
<p>适合读者：初、中、高。</p>
<p>吹毛求疵：太厚，太全。尤其是最后面的语法参考部分，每门语言都拿出一章来介绍用法，但是你阅读之后就会发现，通用的东西多，specific的东西少；对于程序员来说，理解了原理之后，编程语言只需要看文档和API就能搞定；对于普通用户来说，他用既然要用Office系列，就不太可能同时也用 SQL，Perl，Java。这本书太想求全了，因此可能都不讨好。当然了，我是吹毛求疵而已。</p>
</blockquote>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">《正则表达式经典实例》</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<p>最后一本，参考书：《正则表达式经典实例》。这本书在简单介绍正则表达式之后，紧扣“实例”二字，对于每个问题都试图给出多语言的正则解法。如何体现经典呢？一是选例经典，二是解法经典。包括的语言有 Perl/PCRE/.NET/Java/JavaScript/Python/Ruby。这么多的语言，必有一款适合您。也就是说，也有可能多款不适合您 <img src='http://iregex.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  不过，正则表达式是用来解决问题的，只要你能在条目繁多的目录中找到您的问题并找到解法，又何必在乎它还为别人提供了其它语言的解法呢？它就是一本参考书而已，没有必要按照A－Z的顺序精读并背诵，能查到自己需要的东西就是王道。</p>
<p>如果您有做题习惯的话，这本书也适合您。试想，各种各样分门别类的问题，以及相应的解法参考……</p>
<p>最后不能不提的是，该书作者Jan Goyvaerts之一是也RegexBuddy/PowerGREP的开发者。RegexBuddy用起来怎一个爽字了得。</p>
<p>一句话书评：定位明确的较好的正则实例参考书。</p>
<p>适合读者：中。（不太适合新手入门，高手也不必参考书中的和解法。这样说，是不是太低估新手，同时高估高手呢？）</p>
<p>吹毛求疵：书中频频亮相的工具软件当然Jan自己的软件，英文界面，绝对好用但是价格也不菲。不熟悉这些软件的读者可能觉得有些别扭。</p>
</blockquote>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">最好的正则表达式入门书</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<p>最全的书不一定是最好的书。</p>
<p>大家都说好的书不一定是最好的书。</p>
<p>克服了上述书的缺点的书不一定是最好的书。 </p>
<p>适合自己的书，才是最好的书。
</p></blockquote>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">余老师写的《正则表达式傻瓜书》</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<p>余老师的《正则表达式傻瓜书》，虽然尚未面世，仍然非常值得期待，理由如下：</p>
<ul>
<li>如前所言，余老师是《精通正则表达式》的翻译者，对正则表达式有深刻的理解，而且有丰富的使用经验，这是写这本书的先决条件；</li>
<li> 余老师的分析问题、描述问题、讲解知识点的功力非常强。我有幸先睹为快了前几章的样稿，十分佩服。要知道，理解正则表达式，应用正则表达式，和向别人解释正则表达式，其实是截然不同的三件事。</li>
<li>前期就有缜密的计划，中期广泛征求意见，不断接受意见并相应完善。</li>
</ul>
</blockquote>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">结尾</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<p>上面提到的书的Douban链接为：</p>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<ul>
<li><a href="http://book.douban.com/subject/1231697/">大骆驼</a></li>
<li><a href="http://book.douban.com/subject/2154713/">精通正则表达式</a></li>
<li><a href="http://book.douban.com/subject/2269648/">正则表达式必知必会</a></li>
<li><a href="http://book.douban.com/subject/3265338/">正则表达式入门经典</a></li>
<li><a href="http://book.douban.com/subject/4872186/">正则表达式经典实例</a></li>
<li>余老师的博客：<a href="http://www.luanxiang.org/blog/" title="我爱正则表达式" target="_blank">乱象，印记</a>
        </li>
<p><br/>
        </ul>
</blockquote>
<p>任何一门编程语言，坊间都已经充塞着各种各样的书可供参考。而正则表达式的书，放眼望去，寥若晨星。渴望有更多的正则好书涌现出来。或者，我也硬着头皮，写一本试试看？
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://iregex.org/blog/regex-books.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>巧解 JavaScript 中的嵌套替换</title>
		<link>http://iregex.org/blog/javascript-loo-replace.html</link>
		<comments>http://iregex.org/blog/javascript-loo-replace.html#comments</comments>
		<pubDate>Sat, 11 Sep 2010 09:29:29 +0000</pubDate>
		<dc:creator>rex</dc:creator>
				<category><![CDATA[问答]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://iregex.org/?p=144</guid>
		<description><![CDATA[网友wys提问：如何仅使用JavaScript支持的正则语法，将 1234&#60;p&#62; &#60;table&#62; &#60;p&#62; &#60;p&#62; &#160;&#60;/table&#62; &#60;table&#62; &#60;p&#62; &#60;p&#62; &#160;&#60;/table&#62; &#60;p&#62; 中&#60;table&#62;...&#60;/ta... ]]></description>
			<content:encoded><![CDATA[<p>网友wys提问：如何仅使用JavaScript支持的正则语法，将</p>
<div class="codecolorer-container html4strict mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">p</span>&gt;</span> <br />
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">table</span>&gt;</span> <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">p</span>&gt;</span> <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">p</span>&gt;</span> &nbsp;<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">table</span>&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">table</span>&gt;</span> <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">p</span>&gt;</span> <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">p</span>&gt;</span> &nbsp;<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">table</span>&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">p</span>&gt;</span></div></td></tr></tbody></table></div>
<p>中<code class="codecolorer html4strict default"><span class="html4strict"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">table</span>&gt;</span>...<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">table</span>&gt;</span></span></code>之间的<code class="codecolorer html4strict default"><span class="html4strict"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">p</span>&gt;</span></span></code>都替换为<code class="codecolorer html4strict default"><span class="html4strict"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">br</span><span style="color: #66cc66;">/</span>&gt;</span></span></code>?<span id="more-144"></span></p>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">思考</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<p>该问题的难点之一在于JavaScript支持的正则特性实在有限。楼主已经想到了非JavaScript的解法，如下：</p>
<div class="codecolorer-container javascript mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">re<span style="color: #339933;">=</span><span style="color: #009966; font-style: italic;">/(?&lt;=&lt;table.*?)(&lt;p&gt;)(?=.*?&lt;\/table&gt;)/gi</span><span style="color: #339933;">;</span> <br />
<span style="color: #000066;">alert</span> <span style="color: #009900;">&#40;</span>sourcestr.<span style="color: #660066;">replace</span><span style="color: #009900;">&#40;</span>re<span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;&lt;br&gt;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>嗯，思路大致是这样。较真起来，即使JavaScript支持逆序环视，上面答案并不能够如愿运行。原因是<b>带有量词的逆序环视</b>(即在<code class="codecolorer perl default"><span class="perl"><span style="color: #009900;">&#40;</span><span style="color: #339933;">?&lt;=</span><span style="color: #009900;">&#41;</span></span></code>里面使用<code class="codecolorer perl default"><span class="perl"><span style="color: #339933;">?,</span> <span style="color: #339933;">*,</span> <span style="color: #339933;">+,</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span></span></code>这样的量词)是更高级的的语法，极少有语言能够支持（特例是.Net）。
    </p>
<p>但是，像楼主这样的正则问题应该是很普便的一个问题，我们经常需要循环地替换一些内容。该如何解答呢？</p>
</blockquote>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">思路一</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<p>阅读JavaScript的文档，我找到了<a href="http://www.w3schools.com/jsref/jsref_regexp_lastindex.asp" title="我爱正则表达式" target="_blank">lastIndex</a>这样的东东。根据这个东东，我形成了这样的思路：
    </p>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<ul>
<li>先按外层循环，找到第一组较大的匹配。正则代码是<code class="codecolorer perl default"><span class="perl"><span style="color: #339933;">&lt;</span>table<span style="color: #009900;">&#91;</span><span style="color: #339933;">^&gt;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*&gt;</span><span style="color: #009900;">&#91;</span>\<span style="color: #000066;">s</span><span style="color: #0000ff;">\S</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*?&lt;</span>\<span style="color: #339933;">/</span>table<span style="color: #339933;">&gt;</span></span></code></li>
<li>定位到这次匹配结束的起始位置，替换掉这一段字串中所有的<code class="codecolorer perl default"><span class="perl"><span style="color: #009999;">&lt;p&gt;</span></span></code>。</li>
<li>循环执行。</li>
</ul>
</blockquote>
<p>我觉得上述思路大致清晰，但是细节太多（每次匹配涉及3个位置点，一个长度），解起来并非从容不迫，最终的代码想必也不会赏心悦目；尤为重要的是，整个思路像是原始的 Crack，而不是高手的 Hack 。而且思路与正则关系不大。我决定换一条路。</p>
</blockquote>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">思路二</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<p>关键是循环和嵌套。还好不是盗梦空间的深层递归。能否将匹配的内容保护起来，替换完之后再放回原位呢？</p>
<p>想到这里，就豁然开朗了。</p>
<p>思路：先找到所有的匹配内容，记路在数组inner中；</p>
<p>同时使用该正则，将原字串split为另一个数组wrapper；</p>
<p>一个重要的特点是，wrapper一定比inner多一个元素，它一一将inner项隔开，并处于最外层。wrapper 和 inner 的关系，就像是一个手掌的5根指头与4个指缝的关系。将中间的元素取出，记下位置，等处理完之后，再将所有的元素粘合在一起。就是这样简单。代码如下（为了让问题更有普使性，我稍改了一下源字串）：</p>
<div class="codecolorer-container javascript mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;</span> <br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> str<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;&lt;p&gt; &lt;table&gt; &lt;p&gt; ,&lt;p&gt; &nbsp;&lt;/table&gt; &lt;p&gt; &lt;table&gt; &lt;p&gt; &lt;p&gt; &nbsp;&lt;/table&gt; &lt;p&gt; &lt;table&gt; &lt;p&gt; &lt;p&gt; &nbsp;&lt;/table&gt;&quot;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> patt<span style="color: #339933;">=</span><span style="color: #009966; font-style: italic;">/&lt;table[^&gt;]*&gt;[\s\S]*?&lt;\/table&gt;/i</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> wrapper_result<span style="color: #339933;">=</span>str.<span style="color: #660066;">split</span><span style="color: #009900;">&#40;</span>patt<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> inner_result <span style="color: #339933;">=</span> str.<span style="color: #660066;">match</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/&lt;table[^&gt;]*&gt;[\s\S]*?&lt;\/table&gt;/ig</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> len<span style="color: #339933;">=</span>inner_result.<span style="color: #660066;">length</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> final<span style="color: #339933;">=</span>wrapper_result<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>i<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i<span style="color: #339933;">&lt;</span>len<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; tmp<span style="color: #339933;">=</span>inner_result<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">replace</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/&lt;p&gt;/gi</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;&lt;br&gt;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; final<span style="color: #339933;">+=</span>tmp<span style="color: #339933;">+</span>wrapper_result<span style="color: #009900;">&#91;</span>i<span style="color: #339933;">+</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>final<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #339933;">&lt;/</span>script<span style="color: #339933;">&gt;</span></div></td></tr></tbody></table></div>
<p>贴图：</p>
<p><a href="http://iregex.org/blog/javascript-loo-replace.html" target="_blank"><img src="http://i293.photobucket.com/albums/mm60/zhasm/javascript-loop-replace.png" border="0" alt="regex loop"></a>
</p></blockquote>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">更新</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<p>果然是能人辈出，评论更精彩！请看评论中的这则代码：</p>
<div class="codecolorer-container javascript mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>sourcestr.<span style="color: #660066;">replace</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/&lt;table.*?\/table&gt;/ig</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>$1<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><span style="color: #000066; font-weight: bold;">return</span> $1.<span style="color: #660066;">replace</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/&lt;p&gt;/ig</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;&lt;br&gt;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>PS: 本站刚刚添加了评论中代码的解析，可以贴代码了。格式见评论部分的图例显示。谢谢合作！</p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://iregex.org/blog/javascript-loo-replace.html/feed</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>统计最近用过的linux命令</title>
		<link>http://iregex.org/blog/most-frequently-used-linux-commands.html</link>
		<comments>http://iregex.org/blog/most-frequently-used-linux-commands.html#comments</comments>
		<pubDate>Tue, 31 Aug 2010 04:32:59 +0000</pubDate>
		<dc:creator>rex</dc:creator>
				<category><![CDATA[笔记]]></category>
		<category><![CDATA[bash ubuntu]]></category>

		<guid isPermaLink="false">http://iregex.org/?p=142</guid>
		<description><![CDATA[统计最近用过的linux命令。没什么具体用途，练习bash而已。 流程： 从 history 命令中得到最近1000条命令。 删除每行的行号。 记录每一行中的命令。行首的第一个英文单词，以及管道后面的第一... ]]></description>
			<content:encoded><![CDATA[<p>统计最近用过的linux命令。没什么具体用途，练习bash而已。</p>
<p><span id="more-142"></span></p>
<p>流程：</p>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<ul>
<li>从 <code class="codecolorer bash default"><span class="bash"><span style="color: #7a0874; font-weight: bold;">history</span></span></code> 命令中得到最近1000条命令。
        </li>
<li>删除每行的行号。</li>
<li>记录每一行中的命令。行首的第一个英文单词，以及管道后面的第一个英文单词，视为命令名称。</li>
<li>将得到的命令列表排序。</li>
<li>统计每个命令的出现次数，先以次数降序排列，再以命令名称升序排列。</li>
</ul>
</blockquote>
<p>完整的命令为：<code class="codecolorer bash default"><span class="bash"><span style="color: #7a0874; font-weight: bold;">history</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sed</span> <span style="color: #ff0000;">&quot;s#^\s\+[0-9]\+\s\+##g&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #660033;">-oP</span> <span style="color: #ff0000;">&quot;(?&lt;=^|\|)\w+&quot;</span><span style="color: #000000; font-weight: bold;">|</span><span style="color: #c20cb9; font-weight: bold;">sort</span> <span style="color: #000000; font-weight: bold;">|</span><span style="color: #c20cb9; font-weight: bold;">uniq</span> <span style="color: #660033;">-c</span><span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sort</span> -k1,1nr <span style="color: #660033;">-k2</span></span></code>。</p>
<p>以下是本人的ubuntu命令显示：
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; 157 ls<br />
&nbsp; &nbsp; 134 cd<br />
&nbsp; &nbsp; &nbsp;89 pcregrep<br />
&nbsp; &nbsp; &nbsp;76 cat<br />
&nbsp; &nbsp; &nbsp;56 xargs<br />
&nbsp; &nbsp; &nbsp;52 python<br />
&nbsp; &nbsp; &nbsp;49 vim<br />
&nbsp; &nbsp; &nbsp;47 sudo<br />
&nbsp; &nbsp; &nbsp;46 git<br />
&nbsp; &nbsp; &nbsp;44 exit<br />
&nbsp; &nbsp; &nbsp;37 rename<br />
&nbsp; &nbsp; &nbsp;28 echo<br />
&nbsp; &nbsp; &nbsp;27 sed<br />
&nbsp; &nbsp; &nbsp;27 tstp<br />
&nbsp; &nbsp; &nbsp;26 adt<br />
&nbsp; &nbsp; &nbsp;26 grep<br />
&nbsp; &nbsp; &nbsp;19 curl<br />
&nbsp; &nbsp; &nbsp;18 rm<br />
&nbsp; &nbsp; &nbsp;16 history<br />
&nbsp; &nbsp; &nbsp;16 wget<br />
&nbsp; &nbsp; &nbsp;12 ps<br />
&nbsp; &nbsp; &nbsp;10 kill<br />
&nbsp; &nbsp; &nbsp;10 make<br />
&nbsp; &nbsp; &nbsp;10 perl<br />
&nbsp; &nbsp; &nbsp; 8 ll<br />
&nbsp; &nbsp; &nbsp; 8 mv<br />
&nbsp; &nbsp; &nbsp; 8 scp<br />
&nbsp; &nbsp; &nbsp; 8 sfo<br />
&nbsp; &nbsp; &nbsp; 7 ctags<br />
&nbsp; &nbsp; &nbsp; 7 tst<br />
&nbsp; &nbsp; &nbsp; 6 awk<br />
&nbsp; &nbsp; &nbsp; 6 gvim<br />
&nbsp; &nbsp; &nbsp; 6 mkdir<br />
&nbsp; &nbsp; &nbsp; 6 sort<br />
&nbsp; &nbsp; &nbsp; 4 chmod<br />
&nbsp; &nbsp; &nbsp; 4 man<br />
&nbsp; &nbsp; &nbsp; 4 uniq<br />
&nbsp; &nbsp; &nbsp; 3 cjb<br />
&nbsp; &nbsp; &nbsp; 3 md5sum<br />
&nbsp; &nbsp; &nbsp; 3 tt<br />
&nbsp; &nbsp; &nbsp; 3 vmxp<br />
&nbsp; &nbsp; &nbsp; 3 which<br />
&nbsp; &nbsp; &nbsp; 2 chown<br />
&nbsp; &nbsp; &nbsp; 2 ctag<br />
&nbsp; &nbsp; &nbsp; 2 docky<br />
&nbsp; &nbsp; &nbsp; 2 ex<br />
&nbsp; &nbsp; &nbsp; 2 ks<br />
&nbsp; &nbsp; &nbsp; 2 pyton<br />
&nbsp; &nbsp; &nbsp; 2 set<br />
&nbsp; &nbsp; &nbsp; 2 tar<br />
&nbsp; &nbsp; &nbsp; 1 bc<br />
&nbsp; &nbsp; &nbsp; 1 cdcd<br />
&nbsp; &nbsp; &nbsp; 1 cp<br />
&nbsp; &nbsp; &nbsp; 1 cpanm<br />
&nbsp; &nbsp; &nbsp; 1 date<br />
&nbsp; &nbsp; &nbsp; 1 efr<br />
&nbsp; &nbsp; &nbsp; 1 firefox<br />
&nbsp; &nbsp; &nbsp; 1 gawk<br />
&nbsp; &nbsp; &nbsp; 1 gi<br />
&nbsp; &nbsp; &nbsp; 1 less<br />
&nbsp; &nbsp; &nbsp; 1 lua<br />
&nbsp; &nbsp; &nbsp; 1 PWD<br />
&nbsp; &nbsp; &nbsp; 1 re<br />
&nbsp; &nbsp; &nbsp; 1 sleep<br />
&nbsp; &nbsp; &nbsp; 1 tpo<br />
&nbsp; &nbsp; &nbsp; 1 unzip<br />
&nbsp; &nbsp; &nbsp; 1 vi<br />
&nbsp; &nbsp; &nbsp; 1 vm<br />
&nbsp; &nbsp; &nbsp; 1 xarg</div></td></tr></tbody></table></div>
]]></content:encoded>
			<wfw:commentRss>http://iregex.org/blog/most-frequently-used-linux-commands.html/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>anti spam杂谈</title>
		<link>http://iregex.org/blog/anti-spam.html</link>
		<comments>http://iregex.org/blog/anti-spam.html#comments</comments>
		<pubDate>Sun, 15 Aug 2010 02:03:50 +0000</pubDate>
		<dc:creator>rex</dc:creator>
				<category><![CDATA[杂项]]></category>
		<category><![CDATA[akismet]]></category>
		<category><![CDATA[antispam]]></category>
		<category><![CDATA[discuz]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://iregex.org/?p=140</guid>
		<description><![CDATA[本文是一篇随笔，将email的anti spam技术和论坛的防灌水结合在一起讨论。从技术层面出发。不涉及其它。 据说德国有这样一句谚语：没有泡沫的啤酒不是好啤酒。推而广知，可以得到：没人灌... ]]></description>
			<content:encoded><![CDATA[<p>本文是一篇随笔，将email的anti spam技术和论坛的防灌水结合在一起讨论。从技术层面出发。不涉及其它。</p>
<p><span id="more-140"></span></p>
<p>据说德国有这样一句谚语：没有泡沫的啤酒不是好啤酒。推而广知，可以得到：没人灌水的论坛不是好论坛，没有垃圾邮件的邮件系统不是好系统（至少是不知名的系统／电邮地址），没有病毒骚扰的OS不是好的OS，等等。但是，只有泡沫的啤酒也不是什么好啤酒吧？关键是将不需要的内容控制在可以允许的范围内。单就开论坛、维护垃圾邮件的角度出发，审核技术还是很有用，很有必要的。否则，其地盘很快就会淹没在垃圾广告的汪洋大海之中。自己的论坛，自己发广告是为了维持网站开销，但是不请自来的广告是无法容忍的。</p>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">Spam</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<p>
    垃圾邮件有两个特点：<br />
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<ol>
<li>
                <strong>大量</strong>。一封两封垃圾邮件，个人用户可能比较在意，但是对于服务器来说，邮件数以百万计。在这样大的分母下，如果偶然有一两封垃圾邮件被判为合法邮件，或者合法邮件被误判为垃圾，实属正常。
            </li>
<li><strong>不需要</strong>。需要与否，取决于用户的主观判断。大家都认为 porn 和 drug 内容是spam，但是也不排除有人将这类邮件标为 ham 的。
            </li>
</ol>
</blockquote>
</blockquote>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">Anti-Spam</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<p>常用的反垃圾邮件有以下几种方法：
</p>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<ul>
<li>静态关键词列表。如果邮件头（标题，收发件人，电邮地址，正文）含某些关键词（例如Viagra），就将邮件标为Spam 或 Ham。这是最简单的方式，为各大邮件厂商所采用，包括Gmail。它最大的优点是快。缺点多多，一是需要维护（增／改／删 关键词），二是准确率不高（含黑名单中关键词的邮件未必全是Spam，反之亦然），三是不能识别含有干扰因素的邮件。例如，V1agra，发*漂，含这种关键词的邮件，人眼立即能识别它是垃圾邮件，但是静态法就傻了。
        </li>
<li>正则表达式规则表。与静态关键词列表相反，它速度稍慢，但是极其强大和灵活。对于邮件头的扫描，效果尤佳：邮件头是有规律可循的，尤其是对于大量的垃圾邮件而言，不可能不在邮件头中留下蛛丝马迹。<br />
        但是这种方法也有其短板。与上述方法类似，它也需要专人来维护，而且无论从配置难度到维护成本，都远高于前者。对于邮件的正文，正则表达式的扫描速度比较缓慢，尤其是对于精心设计了干扰因素的垃圾邮件。有相当大的一部分邮件，人眼看上去确实也是垃圾邮件，但是使用正则表达式也不好写规则。一个新的规则写手，可能要在准确率与查杀总量的折哀上花费很长一段时间才能掌握其规律。
        </li>
<li>贝叶斯概率法。若已知某些字词经常出现在垃圾邮件中，却很少出现在合法邮件中，当一封邮件含有这些字词时，那么link它是垃圾邮件的可能性就很大。参考此文。<a href="http://home.q.yesky.com/space-4148078-do-blog-id-412454.html" title="我爱正则表达式" target="_blank">贝叶斯过滤技术</a>。<br />
        它最大的优点是，只要有足够健壮的算法，足够的样本空间，其准确率是非常高的。同时，它主要依赖于机器学习，而不需要后期大量的人工干预。</li>
</ul>
</blockquote>
<p>国内有的网站，其内容过滤系统极其简单粗暴，只要出现单个汉字“日”，“操”，“干”等等字眼，就当作垃圾邮件／评论对待，而不分析具体上下文，实在令人又好气又好笑。又有，《百家姓》的常见姓氏用字本身不是垃圾字眼或违禁词汇，如果将其加入静态列表，就会导致连萝卜也无法搜索。其实，用一点点正则表达式（环视）或贝叶斯的技术（条件概率），就能提高过滤质量，皆大欢喜。当然，如果要扫描亿万级的网页，速度的要求肯定要优先于准确度，某些情况下只能做到大致靠谱罢了。然而，频频出错的系统，即使快一点点又有何用（成语：南辕北辙）？ 不过，从来都是宁枉勿纵的。
</p>
<p>由于静态法的特点，注定了列表只能向管理员开放，而对普通游客讳莫如深。这导致了另一种现象：该贴无法显示，是因为含有某关键词。至于哪些词是关键词，不好意思，不能告诉你，怕这个列表一旦公开，想发类似内容的人就能轻易绕过。那就有劳管理员们从严自省，并用心地揣摩圣意。</p>
<p> 动静结合，人、机结合，系统才能越用越新。@chunzi说得很形象：反垃圾邮件的过程，不是拼耐力的马拉松赛跑，而是适者生存的进化。总是魔已先高一丈，道才一尺尺增高，并最终压住魔。同时有新的魔即将出现。</p>
</blockquote>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">一些工具</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<p>如果你说自己的邮箱里其实没多少垃圾邮件，或者即使有也已经自动被转入垃圾箱了，那么有两种可能。一是你所用的邮箱系统本身的反垃圾邮件系统做得不错（有太多太多各式各样的明显的垃圾邮件在进入你的邮箱之前，已经被服务器端给block了）。二是你的邮址没有被爬虫抓到或算出来。</p>
<li>
    <a href="http://spamassassin.apache.org/" title="我爱正则表达式" target="_blank">Spamassassin</a>是一套不错的反垃圾邮件系统。免费，与Apache紧密结合，强大的正则式支持。国内有一个组织专门动态维护一个中文的规则表，在<a href="http://www.ccert.edu.cn/spam/sa/Chinese_rules.htm" title="我爱正则表达式" target="_blank">这里</a>，可以参考。Spamassassin其实也有贝叶斯模块，只是它以正则知名罢了。
    </li>
<li>WordPress 有个 Akismet 插件是用来block 博客上的垃圾评论的。这个设置起来比较傻瓜（只需要申请一个API）即可，效果比较智能，完全不用用户再手工添加任何规则。对于出错的判断，用户有义务提交给Akismet官方，方便它学习新的变种。应该说，用户提交的漏判或误判，是必不可少的语料库。没有用户提交，Akismet就会一根筋地按照既定的思路继续犯同样的错误。
    </li>
</blockquote>
<h3 style="color: #127ADB; font-size:14px; padding-bottom:3px; padding-top:3px; margin:1.5em 0 1em;">个人应用</h3>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<p>国人开发的Discuz是一款不错的论坛程序。不过，它没有较好的反垃圾模块，我一直在颇厌其烦地删除spam和spammer。看了一下Ak的官网，几乎国外知名的论坛程序都有Ak的插件了。我研究了dz的数据结构，使用python写了一个脚本，定时搜索新贴子，将其提交到Ak做判断。如果判为垃圾，则屏蔽贴子，并对该会员实施减分操作。刚开始试用，效果还可以。其实可以做成原生的php插件，集成到dz中的。</p>
<p>流程很直接：</p>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<ul>
<li>定时搜索最新贴子；</li>
<li>对于每一个新贴子:</li>
<blockquote style="border-left:2px solid #DDDDDD; margin:15px 30px 0 10px; padding-left:20px;">
<ul>
<li>提交给Akismet作测试。</li>
<li>如果不是垃圾，忽视之。</li>
<li>如果是垃圾，将该贴转为仅管理员可见。同时将该用户扣分。</li>
</ul>
</blockquote>
<li>总合一下应该执行的操作，执行SQL, Commit。</li>
<li>生成报表，发邮件给管理员。</li>
</ul>
</blockquote>
<p>Ak的开发者页面在这里 <a href="http://akismet.com/development/" title="我爱正则表达式" target="_blank">Akismet API Documentation</a>。我用了其中的<a href="http://www.voidspace.org.uk/python/modules.shtml" title="我爱正则表达式" target="_blank">Python 模块</a> 将其封装为一个class，只需要init和check即可：</p>
<div class="codecolorer-container python mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">#!/usr/bin/python</span><br />
<span style="color: #808080; font-style: italic;"># -*- coding: utf-8 -*-</span><br />
<span style="color: #808080; font-style: italic;">#</span><br />
<span style="color: #808080; font-style: italic;">#author: &nbsp; &nbsp; &nbsp; &nbsp; rex</span><br />
<span style="color: #808080; font-style: italic;">#blog: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; http://iregex.org</span><br />
<span style="color: #808080; font-style: italic;">#filename &nbsp; &nbsp; &nbsp; &nbsp;comment.py</span><br />
<span style="color: #808080; font-style: italic;">#created: &nbsp; &nbsp; &nbsp; &nbsp;2010-08-14 15:58</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">from</span> akismet <span style="color: #ff7700;font-weight:bold;">import</span> Akismet<br />
<br />
<span style="color: #ff7700;font-weight:bold;">class</span> Comment<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.<span style="color: black;">api</span><span style="color: #66cc66;">=</span>Akismet<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">api</span> <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #008000;">None</span> <span style="color: #ff7700;font-weight:bold;">or</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">self</span>.<span style="color: black;">api</span>.<span style="color: black;">verify_key</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'No Valid Akismet API'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; exit<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">def</span> init<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> comment<span style="color: #66cc66;">,</span> <span style="color: #dc143c;">user</span><span style="color: #66cc66;">=</span><span style="color: #483d8b;">''</span><span style="color: #66cc66;">,</span> ip<span style="color: #66cc66;">=</span><span style="color: #483d8b;">''</span><span style="color: #66cc66;">,</span> <span style="color: #dc143c;">email</span><span style="color: #66cc66;">=</span><span style="color: #483d8b;">''</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.<span style="color: #dc143c;">user</span><span style="color: #66cc66;">=</span><span style="color: #dc143c;">user</span>.<span style="color: black;">encode</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;utf-8&quot;</span><span style="color: black;">&#41;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.<span style="color: black;">comment</span><span style="color: #66cc66;">=</span>comment.<span style="color: black;">encode</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;utf-8&quot;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.<span style="color: black;">ip</span><span style="color: #66cc66;">=</span>ip<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.<span style="color: #dc143c;">email</span><span style="color: #66cc66;">=</span><span style="color: #dc143c;">email</span><br />
<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">def</span> check<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">api</span>.<span style="color: black;">comment_check</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">comment</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #483d8b;">'comment_author'</span>: <span style="color: #008000;">self</span>.<span style="color: #dc143c;">user</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #483d8b;">'comment_author_email'</span>:<span style="color: #008000;">self</span>.<span style="color: #dc143c;">email</span><span style="color: #66cc66;">,</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #483d8b;">'user_ip'</span>:<span style="color: #008000;">self</span>.<span style="color: black;">ip</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #483d8b;">'user_agent'</span>:<span style="color: #483d8b;">&quot;Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.8) Gecko/20100723 Ubuntu/10.04 (lucid) Firefox/3.6.8&quot;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#125;</span><span style="color: #66cc66;">,</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>这是程序的主要部分</p>
<div class="codecolorer-container python mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br />81<br />82<br />83<br />84<br />85<br />86<br />87<br />88<br />89<br />90<br />91<br />92<br />93<br />94<br />95<br />96<br />97<br />98<br />99<br />100<br />101<br />102<br />103<br />104<br />105<br />106<br />107<br />108<br />109<br />110<br />111<br />112<br />113<br />114<br />115<br />116<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">#!/usr/bin/python</span><br />
<span style="color: #808080; font-style: italic;"># -*- coding: utf-8 -*-</span><br />
<span style="color: #808080; font-style: italic;">#</span><br />
<span style="color: #808080; font-style: italic;">#author: &nbsp; &nbsp; &nbsp; &nbsp; rex</span><br />
<span style="color: #808080; font-style: italic;">#blog: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; http:#iregex.org</span><br />
<span style="color: #808080; font-style: italic;">#filename &nbsp; &nbsp; &nbsp; &nbsp;dzas.py</span><br />
<span style="color: #808080; font-style: italic;">#created: &nbsp; &nbsp; &nbsp; &nbsp;2010-08-14 15:20</span><br />
<br />
<span style="color: #808080; font-style: italic;">#anti spam for discuz! bbs.</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">from</span> comment <span style="color: #ff7700;font-weight:bold;">import</span> Comment <span style="color: #ff7700;font-weight:bold;">as</span> C<br />
<span style="color: #ff7700;font-weight:bold;">from</span> eml <span style="color: #ff7700;font-weight:bold;">import</span> Email<br />
<br />
<span style="color: #808080; font-style: italic;">#########################################################</span><br />
<span style="color: #808080; font-style: italic;">#global settings</span><br />
send_email_log <span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><br />
<br />
dbhost <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'yourhost.website.com'</span><span style="color: #66cc66;">;</span><br />
dbuser <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'db_user'</span><span style="color: #66cc66;">;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
dbpw <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'yourpassword'</span><span style="color: #66cc66;">;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
dbname <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'dbname'</span><span style="color: #66cc66;">;</span> &nbsp; &nbsp;<br />
dbpre<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'cdb_'</span><br />
<br />
<br />
<span style="color: #808080; font-style: italic;">#punish : punish for the user if he/she publish spam</span><br />
punish_score<span style="color: #66cc66;">=</span><span style="color: #ff4500;">2</span><br />
<br />
<span style="color: #808080; font-style: italic;">#now is 2 hours; you may change</span><br />
sql<span style="color: #66cc66;">=</span><span style="color: black;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #483d8b;">'last_n_hr'</span>:<span style="color: #483d8b;">'''select `%sposts`.pid, `%sposts`.author, `%sposts`.message, `%sposts`.useip, `%smembers`.email, authorid from `%sposts`, `%smembers` where dateline&gt;UNIX_TIMESTAMP(now())-2*3600 and `%sposts`.author=`%smembers`.username order by pid desc;'''</span> % <span style="color: black;">&#40;</span>dbpre<span style="color: #66cc66;">,</span>dbpre<span style="color: #66cc66;">,</span>dbpre<span style="color: #66cc66;">,</span>dbpre<span style="color: #66cc66;">,</span>dbpre<span style="color: #66cc66;">,</span>dbpre<span style="color: #66cc66;">,</span>dbpre<span style="color: #66cc66;">,</span>dbpre<span style="color: #66cc66;">,</span>dbpre<span style="color: #66cc66;">,</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; <span style="color: #483d8b;">'hide'</span>:<span style="color: #483d8b;">'update %sposts set `status`= 1 where pid in (%s);'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; <span style="color: #483d8b;">'punish'</span>:<span style="color: #483d8b;">'update %smembers set credits=credits-%s where uid=%s;'</span><span style="color: #66cc66;">,</span> <br />
&nbsp; &nbsp; <span style="color: #483d8b;">'find_hided'</span>:<span style="color: #483d8b;">&quot;SELECT * FROM &nbsp;`%sposts` WHERE &nbsp;`status`=1;&quot;</span>%<span style="color: black;">&#40;</span>dbpre<span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><br />
<span style="color: black;">&#125;</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">import</span> MySQLdb<br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> init_db<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; db<span style="color: #66cc66;">=</span>MySQLdb.<span style="color: black;">connect</span><span style="color: black;">&#40;</span>host<span style="color: #66cc66;">=</span>dbhost<span style="color: #66cc66;">,</span> <span style="color: #dc143c;">user</span><span style="color: #66cc66;">=</span>dbuser<span style="color: #66cc66;">,</span> passwd<span style="color: #66cc66;">=</span>dbpw<span style="color: #66cc66;">,</span>db<span style="color: #66cc66;">=</span>dbname<span style="color: #66cc66;">,</span> charset<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'utf8'</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> db<br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> hide_spam<span style="color: black;">&#40;</span>db<span style="color: #66cc66;">,</span> spam<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; c<span style="color: #66cc66;">=</span>db.<span style="color: black;">cursor</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; sql_str<span style="color: #66cc66;">=</span>sql<span style="color: black;">&#91;</span><span style="color: #483d8b;">'hide'</span><span style="color: black;">&#93;</span> % <span style="color: black;">&#40;</span>dbpre<span style="color: #66cc66;">,</span><span style="color: #483d8b;">','</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span>spam<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; c.<span style="color: black;">execute</span><span style="color: black;">&#40;</span>sql_str<span style="color: black;">&#41;</span> <br />
&nbsp; &nbsp; db.<span style="color: black;">commit</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> punish<span style="color: black;">&#40;</span>db<span style="color: #66cc66;">,</span>score<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; c<span style="color: #66cc66;">=</span>db.<span style="color: black;">cursor</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> u <span style="color: #ff7700;font-weight:bold;">in</span> score.<span style="color: black;">keys</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; s<span style="color: #66cc66;">=</span>score<span style="color: black;">&#91;</span>u<span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; sql_str<span style="color: #66cc66;">=</span>sql<span style="color: black;">&#91;</span><span style="color: #483d8b;">'punish'</span><span style="color: black;">&#93;</span> % <span style="color: black;">&#40;</span>dbpre<span style="color: #66cc66;">,</span>s*punish_score<span style="color: #66cc66;">,</span>u<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; c.<span style="color: black;">execute</span><span style="color: black;">&#40;</span>sql_str<span style="color: black;">&#41;</span> <br />
&nbsp; &nbsp; db.<span style="color: black;">commit</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> get_msg<span style="color: black;">&#40;</span>db<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; c<span style="color: #66cc66;">=</span>db.<span style="color: black;">cursor</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; c.<span style="color: black;">execute</span><span style="color: black;">&#40;</span>sql<span style="color: black;">&#91;</span><span style="color: #483d8b;">'last_n_hr'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; records<span style="color: #66cc66;">=</span> c.<span style="color: black;">fetchall</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; result<span style="color: #66cc66;">=</span><span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> r <span style="color: #ff7700;font-weight:bold;">in</span> records:<br />
&nbsp; &nbsp; &nbsp; &nbsp; result.<span style="color: black;">append</span><span style="color: black;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'pid'</span>:r<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'user'</span>:r<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'msg'</span>:r<span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'ip'</span>:r<span style="color: black;">&#91;</span><span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'email'</span>:r<span style="color: black;">&#91;</span><span style="color: #ff4500;">4</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'uid'</span>:r<span style="color: black;">&#91;</span><span style="color: #ff4500;">5</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> result<br />
<br />
<span style="color: #808080; font-style: italic;">#send log to admin. change the global variable </span><br />
<span style="color: #808080; font-style: italic;">#send_email_log = 1 or 0 to enable/disable</span><br />
<span style="color: #ff7700;font-weight:bold;">def</span> report<span style="color: black;">&#40;</span>spam<span style="color: #66cc66;">,</span> score<span style="color: black;">&#41;</span>:<br />
<br />
&nbsp; &nbsp; sub<span style="color: #66cc66;">=</span><span style="color: #483d8b;">&quot;%s spams caputured&quot;</span> % <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>spam<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; body<span style="color: #66cc66;">=</span><span style="color: #483d8b;">&quot;spammers including: %s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> % <span style="color: #483d8b;">', '</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span> <span style="color: #008000;">set</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span>m<span style="color: black;">&#91;</span><span style="color: #483d8b;">'user'</span><span style="color: black;">&#93;</span> <span style="color: #ff7700;font-weight:bold;">for</span> m <span style="color: #ff7700;font-weight:bold;">in</span> spam<span style="color: black;">&#93;</span> <span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; body+<span style="color: #66cc66;">=</span><span style="color: #483d8b;">&quot;spam pids including: %s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> % <span style="color: #483d8b;">', '</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span> <span style="color: black;">&#91;</span> <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>m<span style="color: black;">&#91;</span><span style="color: #483d8b;">'pid'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">for</span> m <span style="color: #ff7700;font-weight:bold;">in</span> spam<span style="color: black;">&#93;</span> <span style="color: black;">&#41;</span><br />
&nbsp;<br />
&nbsp; &nbsp; body+<span style="color: #66cc66;">=</span><span style="color: #483d8b;">&quot;useful sql: %s<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> % sql<span style="color: black;">&#91;</span><span style="color: #483d8b;">'find_hided'</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; body+<span style="color: #66cc66;">=</span><span style="color: #483d8b;">&quot;spam preview: <span style="color: #000099; font-weight: bold;">\n</span>%s&quot;</span> % <span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span> m<span style="color: black;">&#91;</span><span style="color: #483d8b;">'msg'</span><span style="color: black;">&#93;</span>.<span style="color: black;">splitlines</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span> <span style="color: #ff7700;font-weight:bold;">for</span> m <span style="color: #ff7700;font-weight:bold;">in</span> spam<span style="color: black;">&#41;</span> <br />
&nbsp; &nbsp; Email<span style="color: black;">&#40;</span>sub.<span style="color: black;">encode</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;utf-8&quot;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span>body.<span style="color: black;">encode</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;utf-8&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> <br />
<br />
<span style="color: #808080; font-style: italic;">#the core part</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> anti_spam<span style="color: black;">&#40;</span>db<span style="color: #66cc66;">,</span> msgs<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; c<span style="color: #66cc66;">=</span>C<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; spam<span style="color: #66cc66;">=</span><span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; score<span style="color: #66cc66;">=</span><span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>.<span style="color: black;">fromkeys</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span>m<span style="color: black;">&#91;</span><span style="color: #483d8b;">'uid'</span><span style="color: black;">&#93;</span> <span style="color: #ff7700;font-weight:bold;">for</span> m <span style="color: #ff7700;font-weight:bold;">in</span> msgs<span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> m <span style="color: #ff7700;font-weight:bold;">in</span> msgs:<br />
&nbsp; &nbsp; &nbsp; &nbsp; c.<span style="color: black;">init</span><span style="color: black;">&#40;</span>m<span style="color: black;">&#91;</span><span style="color: #483d8b;">'msg'</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span> m<span style="color: black;">&#91;</span><span style="color: #483d8b;">'user'</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span> m<span style="color: black;">&#91;</span><span style="color: #483d8b;">'ip'</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span> m<span style="color: black;">&#91;</span><span style="color: #483d8b;">'email'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> c.<span style="color: black;">check</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; score<span style="color: black;">&#91;</span>m<span style="color: black;">&#91;</span><span style="color: #483d8b;">'uid'</span><span style="color: black;">&#93;</span><span style="color: black;">&#93;</span>+<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; spam.<span style="color: black;">append</span><span style="color: black;">&#40;</span>m<span style="color: black;">&#41;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> s <span style="color: #ff7700;font-weight:bold;">in</span> score.<span style="color: black;">keys</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> score<span style="color: black;">&#91;</span>s<span style="color: black;">&#93;</span><span style="color: #66cc66;">==</span><span style="color: #ff4500;">0</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">del</span> score<span style="color: black;">&#91;</span>s<span style="color: black;">&#93;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> score <span style="color: #ff7700;font-weight:bold;">and</span> spam: <br />
&nbsp; &nbsp; &nbsp; &nbsp; hide_spam<span style="color: black;">&#40;</span>db<span style="color: #66cc66;">,</span> <span style="color: black;">&#91;</span><span style="color: #008000;">str</span><span style="color: black;">&#40;</span>m<span style="color: black;">&#91;</span><span style="color: #483d8b;">'pid'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">for</span> m <span style="color: #ff7700;font-weight:bold;">in</span> spam<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; punish<span style="color: black;">&#40;</span>db<span style="color: #66cc66;">,</span> score<span style="color: black;">&#41;</span> <br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> send_email_log:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; report<span style="color: black;">&#40;</span>spam<span style="color: #66cc66;">,</span> score<span style="color: black;">&#41;</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>: <br />
&nbsp; &nbsp; db<span style="color: #66cc66;">=</span>init_db<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; msg<span style="color: #66cc66;">=</span>get_msg<span style="color: black;">&#40;</span>db<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; anti_spam<span style="color: black;">&#40;</span>db<span style="color: #66cc66;">,</span> msg<span style="color: black;">&#41;</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">if</span> __name__<span style="color: #66cc66;">==</span><span style="color: #483d8b;">'__main__'</span>:<br />
&nbsp; &nbsp; main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://iregex.org/blog/anti-spam.html/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>正则凡客</title>
		<link>http://iregex.org/blog/fanke.html</link>
		<comments>http://iregex.org/blog/fanke.html#comments</comments>
		<pubDate>Tue, 10 Aug 2010 12:00:51 +0000</pubDate>
		<dc:creator>rex</dc:creator>
				<category><![CDATA[杂项]]></category>

		<guid isPermaLink="false">http://iregex.org/?p=139</guid>
		<description><![CDATA[按需替换，精准搜索； 有时贪婪，有时懒惰。 喜欢正则，不喜欢回溯； 喜欢用正则解决问题，也知道并非所有问题都能用正则解决。 喜欢在论坛上讨论疑点，也喜欢在博客上分享心得。 自学... ]]></description>
			<content:encoded><![CDATA[<p>按需替换，精准搜索；<br />
有时贪婪，有时懒惰。<br />
喜欢正则，不喜欢回溯；<br />
喜欢用正则解决问题，也知道并非所有问题都能用正则解决。<br />
喜欢在<a href="http://regex.me">论坛</a>上讨论疑点，也喜欢在<a href="http://iregex.org">博客</a>上分享心得。<br />
自学而未成才，不是什么大牛，我是一名正则凡客。 </p>
]]></content:encoded>
			<wfw:commentRss>http://iregex.org/blog/fanke.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

