﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-NLPIR爱好者</title><link>http://www.blogjava.net/katsutou/</link><description /><language>zh-cn</language><lastBuildDate>Sun, 12 Apr 2026 06:05:24 GMT</lastBuildDate><pubDate>Sun, 12 Apr 2026 06:05:24 GMT</pubDate><ttl>60</ttl><item><title>关于PYTHON爬虫代理的很好的教程</title><link>http://www.blogjava.net/katsutou/archive/2018/11/18/433505.html</link><dc:creator>Seraphi</dc:creator><author>Seraphi</author><pubDate>Sun, 18 Nov 2018 08:56:00 GMT</pubDate><guid>http://www.blogjava.net/katsutou/archive/2018/11/18/433505.html</guid><wfw:comment>http://www.blogjava.net/katsutou/comments/433505.html</wfw:comment><comments>http://www.blogjava.net/katsutou/archive/2018/11/18/433505.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/katsutou/comments/commentRss/433505.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/katsutou/services/trackbacks/433505.html</trackback:ping><description><![CDATA[<div><div>https://www.jianshu.com/p/ebf2e5b34aad</div></div><img src ="http://www.blogjava.net/katsutou/aggbug/433505.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/katsutou/" target="_blank">Seraphi</a> 2018-11-18 16:56 <a href="http://www.blogjava.net/katsutou/archive/2018/11/18/433505.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MacTex的pkuthss配置</title><link>http://www.blogjava.net/katsutou/archive/2017/02/28/432345.html</link><dc:creator>Seraphi</dc:creator><author>Seraphi</author><pubDate>Tue, 28 Feb 2017 14:13:00 GMT</pubDate><guid>http://www.blogjava.net/katsutou/archive/2017/02/28/432345.html</guid><wfw:comment>http://www.blogjava.net/katsutou/comments/432345.html</wfw:comment><comments>http://www.blogjava.net/katsutou/archive/2017/02/28/432345.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/katsutou/comments/commentRss/432345.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/katsutou/services/trackbacks/432345.html</trackback:ping><description><![CDATA[今天换了Macbook pro来写毕业论文，发现有一大堆中文相关的问题导致编译错误。经过一晚上的研究，终于解决。主要有以下要点：<br /><br />1. 由于MacTex对CTex的支持并不如TexLive那么好，在用pkuthss 1.7.3模板写论文的时候，首先需要对pkuthss.cls文件进行修改：<br /><div>需要将原来的\LoadClass[hyperref, cs4size, fntef, fancyhdr]{ctexbook}[2011/03/11]一行改为如下形式：</div><div>\LoadClass[fontset = windowsold,cs4size,UTF8,fancyhdr,hyperref,fntef,openany]{ctexbook}[2011/03/11]<br /><br />2.在进行上述改动后，发现还是不行。提示simhei.ttf, simsong.ttc, simfang.ttf找不到。这个时候，需要将上述三种字体超链接到tex的目录下。<br /><br />具体方法如下：<br />（1）在tex对应的下列目录建立Chinese文件夹：/usr/local/texlive/2016/texmf-dist/fonts/truetype/<br />（2）将SimHei SimSong Fangsong三种字体超链接到上述目录。这三种字体可以在/Library/Fonts/Microsoft中找到，注意的是放到tex下时，文件名需要小写，黑体和仿宋后缀名为.ttf，宋体为.ttc<br />（3）sudo texhash<br /><br />3.再编译的时候发现已经可以了！Yeah~~~</div><img src ="http://www.blogjava.net/katsutou/aggbug/432345.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/katsutou/" target="_blank">Seraphi</a> 2017-02-28 22:13 <a href="http://www.blogjava.net/katsutou/archive/2017/02/28/432345.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>pulp配置步骤：安装GLPK</title><link>http://www.blogjava.net/katsutou/archive/2016/05/27/430684.html</link><dc:creator>Seraphi</dc:creator><author>Seraphi</author><pubDate>Fri, 27 May 2016 06:25:00 GMT</pubDate><guid>http://www.blogjava.net/katsutou/archive/2016/05/27/430684.html</guid><wfw:comment>http://www.blogjava.net/katsutou/comments/430684.html</wfw:comment><comments>http://www.blogjava.net/katsutou/archive/2016/05/27/430684.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/katsutou/comments/commentRss/430684.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/katsutou/services/trackbacks/430684.html</trackback:ping><description><![CDATA[<p style="margin: 0px 0px 1em; padding: 0px; border: 0px; font-size: 15px; clear: both; color: #242729; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; line-height: 19.5px; background-color: #ffffff;">I have successfully run your code after doing the following two steps:</p><ol style="margin: 0px 0px 1em 30px; padding: 0px; border: 0px; font-size: 15px; color: #242729; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; line-height: 19.5px; background-color: #ffffff;"><li style="margin: 0px 0px 0.5em; padding: 0px; border: 0px; word-wrap: break-word;"><p style="margin: 0px 0px 1em; padding: 0px; border: 0px; clear: both;">Download GLPK from</p><p style="margin: 0px; padding: 0px; border: 0px; clear: both;"><a href="http://sourceforge.net/projects/winglpk/files/latest/download" rel="nofollow" style="margin: 0px; padding: 0px; border: 0px; color: #005999; text-decoration: none; cursor: pointer;">http://sourceforge.net/projects/winglpk/files/latest/download</a>&nbsp;(as mentioned by oyvind)</p></li><li style="margin: 0px 0px 0.5em; padding: 0px; border: 0px; word-wrap: break-word;">Unzip it into (for example) :&nbsp;<code style="margin: 0px; padding: 1px 5px; border: 0px; font-size: 13px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, sans-serif; white-space: pre-wrap; background-color: #eff0f1;">C:\glpk_is_here\</code></li><li style="margin: 0px 0px 0.5em; padding: 0px; border: 0px; word-wrap: break-word;"><p style="margin: 0px; padding: 0px; border: 0px; clear: both;">Add GLPK binaries to your system path before running python&nbsp;<code style="margin: 0px; padding: 1px 5px; border: 0px; font-size: 13px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, sans-serif; white-space: pre-wrap; background-color: #eff0f1;">C:\&gt;<strong style="margin: 0px; padding: 0px; border: 0px;">set PATH=%PATH%;C:\glpk_is_here\glpk-4.55\w64</strong> </code></p></li><li style="margin: 0px 0px 0.5em; padding: 0px; border: 0px; word-wrap: break-word;"><p style="margin: 0px; padding: 0px; border: 0px; clear: both;"><strong style="margin: 0px; padding: 0px; border: 0px;">Using the same cmd window from (3)</strong>, use python/ipython to run your code:<br /><code style="margin: 0px; padding: 1px 5px; border: 0px; font-size: 13px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, sans-serif; white-space: pre-wrap; background-color: #eff0f1;">C:\&gt;<strong style="margin: 0px; padding: 0px; border: 0px;">ipython your_code.py</strong> </code></p></li><li style="margin: 0px; padding: 0px; border: 0px; word-wrap: break-word;"><p style="margin: 0px; padding: 0px; border: 0px; clear: both;">See the results&nbsp;<code style="margin: 0px; padding: 1px 5px; border: 0px; font-size: 13px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, sans-serif; white-space: pre-wrap; background-color: #eff0f1;">Out[4]: 2.0</code></p></li></ol><p style="margin: 0px 0px 1em; padding: 0px; border: 0px; font-size: 15px; clear: both; color: #242729; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; line-height: 19.5px; background-color: #ffffff;">Good luck.</p><img src ="http://www.blogjava.net/katsutou/aggbug/430684.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/katsutou/" target="_blank">Seraphi</a> 2016-05-27 14:25 <a href="http://www.blogjava.net/katsutou/archive/2016/05/27/430684.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转：WINDOWS搭建Discuz</title><link>http://www.blogjava.net/katsutou/archive/2013/03/11/396278.html</link><dc:creator>Seraphi</dc:creator><author>Seraphi</author><pubDate>Mon, 11 Mar 2013 03:09:00 GMT</pubDate><guid>http://www.blogjava.net/katsutou/archive/2013/03/11/396278.html</guid><wfw:comment>http://www.blogjava.net/katsutou/comments/396278.html</wfw:comment><comments>http://www.blogjava.net/katsutou/archive/2013/03/11/396278.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/katsutou/comments/commentRss/396278.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/katsutou/services/trackbacks/396278.html</trackback:ping><description><![CDATA[<h1><a id="cb_post_title_url" href="http://www.cnblogs.com/ajunForNet/archive/2012/09/12/2682063.html" style="margin: 0px; padding: 0px; color: #075db3; text-decoration: initial;">Windows7&amp;IIS7.5部署Discuz全攻略</a></h1><div style="margin: 0px; clear: both; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; line-height: 18px; background-color: #fefef2;"></div><div style="margin: 5px 0px 0px; padding: 5px 2px 5px 5px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #fefef2;"><div id="cnblogs_post_body" style="margin: 0px; word-break: normal !important;"><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">原贴：<a href="http://www.cnblogs.com/ajunForNet/archive/2012/09/12/2682063.html">http://www.cnblogs.com/ajunForNet/archive/2012/09/12/2682063.html</a><br /><br />组长说在内网部署一个论坛，这可难不倒我，装个Discuz嘛。<br style="margin: 0px; padding: 0px;" />部署环境就一台普通的PC，四核i3，Windows7。这就开搞了。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;"></p><h3>准备工作</h3><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">系统是Windows 7 专业版，自带IIS7.5（家庭版不带）。IIS7开始带了FastCgi，对PHP支持好了许多，所以也不必装Apache啦。<br style="margin: 0px; padding: 0px;" />下载&nbsp;<a href="http://windows.php.net/download/" style="margin: 0px; padding: 0px; color: #075db3;">PHP 5.4</a>、&nbsp;<a href="http://dev.mysql.com/downloads/mysql/" style="margin: 0px; padding: 0px; color: #075db3;">MySQL 5.5</a>&nbsp;以及Discuz X2。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">对于IIS7 FastCgi，我们应当选择VC9编译的线程安全的版本。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;"></p><h3>安装PHP</h3><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">解压PHP，我给的路径是C:\PHP，大伙儿随意<br style="margin: 0px; padding: 0px;" />把php.ini-production改名为php.ini（用于开发环境的话，就改那个development）</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">修改扩展路径</p><blockquote style="margin-right: 0px; padding-top: 10px; padding-right: 60px; padding-left: 60px; background-image: url(http://common.cnblogs.com/Skins/coffee/images/comment.gif); min-height: 35px; line-height: 1.6em; background-position: 25px 0px; background-repeat: no-repeat no-repeat;"><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5; color: #000000;">extension_dir = "./ext"</p></blockquote><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;"><span style="margin: 0px; padding: 0px; line-height: 1.5;">启用MySQL扩展（即去掉分号）</span></p><blockquote style="margin-right: 0px; padding-top: 10px; padding-right: 60px; padding-left: 60px; background-image: url(http://common.cnblogs.com/Skins/coffee/images/comment.gif); min-height: 35px; line-height: 1.6em; background-position: 25px 0px; background-repeat: no-repeat no-repeat;"><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5; color: #000000;"><span style="margin: 0px; padding: 0px; line-height: 1.5;">extension=php_MySQL.dll</span></p></blockquote><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">修改时区</p><blockquote style="margin-right: 0px; padding-top: 10px; padding-right: 60px; padding-left: 60px; background-image: url(http://common.cnblogs.com/Skins/coffee/images/comment.gif); min-height: 35px; line-height: 1.6em; background-position: 25px 0px; background-repeat: no-repeat no-repeat;"><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5; color: #000000;">date.timezone=Asia/Shanghai</p></blockquote><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">完了可以尝试在命令行中执行以下PHP：</p><blockquote style="margin-right: 0px; padding-top: 10px; padding-right: 60px; padding-left: 60px; background-image: url(http://common.cnblogs.com/Skins/coffee/images/comment.gif); min-height: 35px; line-height: 1.6em; background-position: 25px 0px; background-repeat: no-repeat no-repeat;"><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5; color: #000000;">cd C:\PHP<br style="margin: 0px; padding: 0px;" />php -v</p></blockquote><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">可以看到php的版本信息，如果把dll文件不存在的扩展打开了的话，会有提示。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;"></p><h3>配置IIS</h3><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">IIS容易对付，不过先得把确保这几项已经装上：</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;"><img alt="" src="http://pic002.cnblogs.com/images/2012/46377/2012030119285947.png" style="margin: 0px; padding: 0px; border: 0px;" /></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;"><strong style="margin: 0px; padding: 0px;">1、添加模块映射</strong><br style="margin: 0px; padding: 0px;" />启动IIS管理器，对服务器设置&#8220;处理程序映射&#8221;，&#8221;添加模块映射&#8220;：<br style="margin: 0px; padding: 0px;" />（图）<br style="margin: 0px; padding: 0px;" />注意，设置可执行文件路径的时候，要选择exe。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;"><img alt="" src="http://pic002.cnblogs.com/images/2012/46377/2012030119293337.png" style="margin: 0px; padding: 0px; border: 0px;" /></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;"><strong style="margin: 0px; padding: 0px;">2、添加index.php为默认文档</strong><br style="margin: 0px; padding: 0px;" />对服务器设置&#8220;默认文档&#8221;，添加index.php</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;"><br style="margin: 0px; padding: 0px;" /><strong style="margin: 0px; padding: 0px;">3、创建新站点</strong><br style="margin: 0px; padding: 0px;" />接着在创建一个新的站点，并创建一个目录存放你的网站，C:\Forum<br style="margin: 0px; padding: 0px;" />主机名填你想要绑定的域名，对于一台服务器上有多个网站的情况，域名几乎是必须的。<br style="margin: 0px; padding: 0px;" />当然啦，内网的话，就改hosts随便弄个上去吧。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;"></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;"><strong style="margin: 0px; padding: 0px;">4、设置程序池</strong><br style="margin: 0px; padding: 0px;" />去应用程序池，设置刚才创建的站点对应的程序池，把.Net framework版本设成无托管代码。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">重启IIS，在网站目录下放一个index.php，内容很简单：<br style="margin: 0px; padding: 0px;" />&lt;?php phpinfo(); ?&gt;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">访问网站，设置无误的话应该能看到PHP的系统信息。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;"></p><h3>安装MySQL</h3><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">安装MySQL挺容易的，按照<a href="http://www.discuz.net/thread-1796583-1-1.html" style="margin: 0px; padding: 0px; color: #075db3;">Discuz给出的教程</a>就可以了。<br style="margin: 0px; padding: 0px;" />因为我下的是UTF8版本的Discuz，所以在选择字符编码那一步选的UTF8。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">至于改数据库目录以及移动那个dll，看上去完全没那个必要，我也就没弄。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;"></p><h3>安装Discuz</h3><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">最烦的都搞定了，最后把安装包里<span style="margin: 0px; padding: 0px; line-height: 1.5; color: #ff0000;">upload里面的东西</span>都复制到网站目录下，<br style="margin: 0px; padding: 0px;" />访问网站下的install目录就能看到安装界面<br style="margin: 0px; padding: 0px;" />剩下的不用说了吧&#183;&#183;&#183;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">得记得安装完了以后，进UCenter-&gt;全局-&gt;域名设置-&gt;应用域名，把论坛的域名给设好了，<br style="margin: 0px; padding: 0px;" />否则论坛首页就是个500</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;"></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">Over.</p></div></div><img src ="http://www.blogjava.net/katsutou/aggbug/396278.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/katsutou/" target="_blank">Seraphi</a> 2013-03-11 11:09 <a href="http://www.blogjava.net/katsutou/archive/2013/03/11/396278.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux一些常用命令</title><link>http://www.blogjava.net/katsutou/archive/2013/03/06/396113.html</link><dc:creator>Seraphi</dc:creator><author>Seraphi</author><pubDate>Wed, 06 Mar 2013 02:38:00 GMT</pubDate><guid>http://www.blogjava.net/katsutou/archive/2013/03/06/396113.html</guid><wfw:comment>http://www.blogjava.net/katsutou/comments/396113.html</wfw:comment><comments>http://www.blogjava.net/katsutou/archive/2013/03/06/396113.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/katsutou/comments/commentRss/396113.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/katsutou/services/trackbacks/396113.html</trackback:ping><description><![CDATA[nohup + 命令 + &amp; 后台运行程序（连接服务器时，运行程序）<img src ="http://www.blogjava.net/katsutou/aggbug/396113.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/katsutou/" target="_blank">Seraphi</a> 2013-03-06 10:38 <a href="http://www.blogjava.net/katsutou/archive/2013/03/06/396113.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转：latex安装</title><link>http://www.blogjava.net/katsutou/archive/2013/02/16/395329.html</link><dc:creator>Seraphi</dc:creator><author>Seraphi</author><pubDate>Sat, 16 Feb 2013 05:51:00 GMT</pubDate><guid>http://www.blogjava.net/katsutou/archive/2013/02/16/395329.html</guid><wfw:comment>http://www.blogjava.net/katsutou/comments/395329.html</wfw:comment><comments>http://www.blogjava.net/katsutou/archive/2013/02/16/395329.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/katsutou/comments/commentRss/395329.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/katsutou/services/trackbacks/395329.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: LaTeX（&nbsp;LATEX，音译&#8220;拉泰赫&#8221;）是一种基于TeX的排版系统，由&nbsp;美国&nbsp;计算机学家&nbsp;莱斯利&#183;兰伯特（Leslie Lamport）在20世纪80年代初期开发，利用这种格式，即使使用者没有排版和程序设计的知识也可以充分发挥由TeX所提供的强大功能，能在几天，甚至几小时内生成很多具有书籍质量的印刷品。&nbsp;你可以在...&nbsp;&nbsp;<a href='http://www.blogjava.net/katsutou/archive/2013/02/16/395329.html'>阅读全文</a><img src ="http://www.blogjava.net/katsutou/aggbug/395329.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/katsutou/" target="_blank">Seraphi</a> 2013-02-16 13:51 <a href="http://www.blogjava.net/katsutou/archive/2013/02/16/395329.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转:python正则表达式基础</title><link>http://www.blogjava.net/katsutou/archive/2013/02/11/395299.html</link><dc:creator>Seraphi</dc:creator><author>Seraphi</author><pubDate>Mon, 11 Feb 2013 08:28:00 GMT</pubDate><guid>http://www.blogjava.net/katsutou/archive/2013/02/11/395299.html</guid><wfw:comment>http://www.blogjava.net/katsutou/comments/395299.html</wfw:comment><comments>http://www.blogjava.net/katsutou/archive/2013/02/11/395299.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/katsutou/comments/commentRss/395299.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/katsutou/services/trackbacks/395299.html</trackback:ping><description><![CDATA[<div clearfix"="" style="zoom: 1; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 12px; line-height: normal;"><h2>Python正则</h2></div><div id="content" mod-cs-content="" text-content=""  clearfix"="" style="zoom: 1; width: 758px; overflow: hidden; line-height: 1.5; margin: 7px 0px 10px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti;">初学Python，对Python的文字处理能力有很深的印象，除了str对象自带的一些方法外，就是正则表达式这个强大的模块了。但是对于初学者来说，要用好这个功能还是有点难度<br /><br />，我花了好长时间才摸出了点门道。由于我记性不好，很容易就忘事，所以还是写下来比较好一些，同时也可以加深印象，整理思路。<br /><br />由于我是初学，所以肯定会有些错误，还望高手不吝赐教，指出我的错误。<br /><br />1 Python正则式的基本用法<br /><br />Python的正则表达式的模块是&#8216;re&#8217;,它的基本语法规则就是指定一个字符序列，比如你要在一个字符串s=&#8217;123abc456&#8217;中查找字符串&#8217;abc&#8217;,只要这样写：<br /><br />&gt;&gt;&gt; import re<br /><br />&gt;&gt;&gt; s='123abc456eabc789'<br /><br />&gt;&gt;&gt; re.findall(r&#8217;abc&#8217;,s)<br /><br />结果就是：<br /><br />['abc', 'abc']<br /><br />这里用到的函数&#8221;findall(rule , target [,flag] )&#8221; 是个比较直观的函数，就是在目标字符串中查找符合规则的字符串。第一个参数是规则，第二个参数是目标字符串，后面<br /><br />还可以跟一个规则选项（选项功能将在compile函数的说明中详细说明）。返回结果结果是一个列表，中间存放的是符合规则的字符串。如果没有符合规则的字符串被找到，就返<br /><br />回一个空列表。<br /><br />&nbsp;<br /><br />为什么要用r&#8217; ..&#8216;字符串（raw字符串）？由于正则式的规则也是由一个字符串定义的，而在正则式中大量使用转义字符&#8217;/&#8217;，如果不用raw字符串，则在需要写一个&#8217;/&#8217;的地<br /><br />方，你必须得写成&#8217;//&#8217;,那么在要从目标字符串中匹配一个&#8217;/&#8217;的时候，你就得写上4个&#8217;/&#8217;成为&#8217;////&#8217;！这当然很麻烦，也不直观，所以一般都使用r&#8217;&#8217;来定义规则字符<br /><br />串。当然，某些情况下，可能不用raw字符串比较好。<br /><br />&nbsp;<br /><br />以上是个最简单的例子。当然实际中这么简单的用法几乎没有意义。为了实现复杂的规则查找，re规定了若干语法规则。它们分为这么几类：<br /><br />功能字符：&nbsp;&nbsp;&nbsp; &#8216;.&#8217; &#8216;*&#8217; &#8216;+&#8217; &#8216;|&#8217; &#8216;?&#8217; &#8216;^&#8217; &#8216;$&#8217; &#8216;/&#8217;等，它们有特殊的功能含义。特别是&#8217;/&#8217;字符，它是转义引导符号，跟在它后面的字符一般有特殊的含义。<br /><br />规则分界符： &#8216;[&#8216; &#8216;]&#8217; &#8216;（&#8217; &#8216;）&#8217; &#8216;{&#8216; &#8216;}&#8217;等，也就是几种括号了。<br /><br />预定义转义字符集：&#8220;/d&#8221;&nbsp; &#8220;/w&#8221; &#8220;/s&#8221; 等等，它们是以字符&#8217;/&#8217;开头，后面接一个特定字符的形式，用来指示一个预定义好的含义。<br /><br />其它特殊功能字符：&#8217;#&#8217; &#8216;!&#8217; &#8216;:&#8217; &#8216;-&#8216;等，它们只在特定的情况下表示特殊的含义，比如(?# &#8230;)就表示一个注释，里面的内容会被忽略。<br /><br />&nbsp;<br /><br />下面来一个一个的说明这些规则的含义，不过说明的顺序并不是按照上面的顺序来的，而是我认为由浅入深，由基本到复杂的顺序来编排的。同时为了直观，在说明的过程中尽量<br /><br />多举些例子以方便理解。<br /><br />1.1基本规则<br /><br />&nbsp;<br /><br />&#8216;[&#8216;&nbsp; &#8216;]&#8217;字符集合设定符<br /><br />首先说明一下字符集合设定的方法。由一对方括号括起来的字符，表明一个字符集合，能够匹配包含在其中的任意一个字符。比如[abc123]，表明字符&#8217;a&#8217; &#8216;b&#8217; &#8216;c&#8217; &#8216;1&#8217;&nbsp;<br /><br />&#8216;2&#8217; &#8216;3&#8217;都符合它的要求。可以被匹配。<br /><br />在&#8217;[&#8216; &#8216;]&#8217;中还可以通过&#8217;-&#8216; 减号来指定一个字符集合的范围，比如可以用[a-zA-Z]来指定所以英文字母的大小写，因为英文字母是按照从小到大的顺序来排的。你不可以<br /><br />把大小的顺序颠倒了，比如写成[z-a]就不对了。<br /><br />如果在&#8217;[&#8216; &#8216;]&#8217;里面的开头写一个&#8216;^&#8217; 号，则表示取非，即在括号里的字符都不匹配。如[^a-zA-Z]表明不匹配所有英文字母。但是如果&#8216;^&#8217;不在开头，则它就不再是表示<br /><br />取非，而表示其本身，如[a-z^A-Z]表明匹配所有的英文字母和字符&#8217;^&#8217;。<br /><br />&nbsp;<br /><br />&#8216;|&#8217;&nbsp;&nbsp;&nbsp; 或规则<br /><br />将两个规则并列起来，以&#8216;|&#8217;连接，表示只要满足其中之一就可以匹配。比如<br /><br />[a-zA-Z]|[0-9]表示满足数字或字母就可以匹配，这个规则等价于[a-zA-Z0-9]<br /><br />注意：关于&#8217;|&#8217;要注意两点：<br /><br />第一，&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 它在&#8217;[&#8216; &#8216;]&#8217;之中不再表示或，而表示他本身的字符。如果要在&#8217;[&#8216; &#8216;]&#8217;外面表示一个&#8217;|&#8217;字符，必须用反斜杠引导，即&#8217;/|&#8217; ;&nbsp;<br /><br />第二，&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 它的有效范围是它两边的整条规则，比如&#8216;dog|cat&#8217;匹配的是&#8216;dog&#8217;和&#8217;cat&#8217;，而不是&#8217;g&#8217;和&#8217;c&#8217;。如果想限定它的有效范围，必需使用一个无捕获组&#8216;<br /><br />(?: )&#8217;包起来。比如要匹配&#8216;I have a dog&#8217;或&#8217;I have a cat&#8217;，需要写成r&#8217;I have a (?:dog|cat)&#8217;，而不能写成r&#8217;I have a dog|cat&#8217;<br /><br />例<br /><br />&gt;&gt;&gt; s = &#8216;I have a dog , I have a cat&#8217;<br /><br />&gt;&gt;&gt; re.findall( r&#8217;I have a (?:dog|cat)&#8217; , s )<br /><br />['I have a dog', 'I have a cat']&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #正如我们所要的<br /><br />下面再看看不用无捕获组会是什么后果：<br /><br />&gt;&gt;&gt; re.findall( r&#8217;I have a dog|cat&#8217; , s )<br /><br />['I have a dog', 'cat']&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #它将&#8217;I have a dog&#8217;和&#8217;cat&#8217;当成两个规则了<br /><br />至于无捕获组的使用，后面将仔细说明。这里先跳过。<br /><br />&nbsp;<br /><br />&#8216;.&#8217;&nbsp;&nbsp;&nbsp; 匹配所有字符<br /><br />匹配除换行符&#8217;/n&#8217;外的所有字符。如果使用了&#8217;S&#8217;选项，匹配包括&#8217;/n&#8217;的所有字符。<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 例：<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &gt;&gt;&gt; s=&#8217;123 /n456 /n789&#8217;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &gt;&gt;&gt; findall(r&#8216;.+&#8217;,s)<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ['123', '456', '789']<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &gt;&gt;&gt; re.findall(r&#8216;.+&#8217; , s , re.S)<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ['123/n456/n789']<br /><br />&nbsp;<br /><br />&#8216;^&#8217;和&#8217;$&#8217;匹配字符串开头和结尾<br /><br />注意&#8217;^&#8217;不能在&#8216;[ ]&#8217;中，否则含意就发生变化，具体请看上面的&#8217;[&#8216; &#8216;]&#8217;说明。在多行模式下，它们可以匹配每一行的行首和行尾。具体请看后面compile函数说明的&#8217;M<br /><br />&#8217;选项部分<br /><br />&nbsp;<br /><br />&#8216;/d&#8217;匹配数字<br /><br />这是一个以&#8217;/&#8217;开头的转义字符，&#8217;/d&#8217;表示匹配一个数字，即等价于[0-9]<br /><br />&#8216;/D&#8217;匹配非数字<br /><br />这个是上面的反集，即匹配一个非数字的字符，等价于[^0-9]。注意它们的大小写。下面我们还将看到Python的正则规则中很多转义字符的大小写形式，代表互补的关系。这样很<br /><br />好记。<br /><br />&nbsp;<br /><br />&#8216;/w&#8217;匹配字母和数字<br /><br />匹配所有的英文字母和数字，即等价于[a-zA-Z0-9]。<br /><br />&#8216;/W&#8217;匹配非英文字母和数字<br /><br />即&#8217;/w&#8217;的补集，等价于[^a-zA-Z0-9]。<br /><br />&nbsp;<br /><br />&#8216;/s&#8217;匹配间隔符<br /><br />即匹配空格符、制表符、回车符等表示分隔意义的字符，它等价于[ /t/r/n/f/v]。（注意最前面有个空格)<br /><br />&#8216;/S&#8217;匹配非间隔符<br /><br />即间隔符的补集，等价于[^ /t/r/n/f/v]<br /><br />&nbsp;<br /><br />&#8216;/A&#8217;匹配字符串开头<br /><br />匹配字符串的开头。它和&#8217;^&#8217;的区别是，&#8217;/A&#8217;只匹配整个字符串的开头，即使在&#8217;M&#8217;模式下，它也不会匹配其它行的很首。<br /><br />&#8216;/Z&#8217;匹配字符串结尾<br /><br />匹配字符串的结尾。它和&#8217;$&#8217;的区别是，&#8217;/Z&#8217;只匹配整个字符串的结尾，即使在&#8217;M&#8217;模式下，它也不会匹配其它各行的行尾。<br /><br />例：<br /><br />&gt;&gt;&gt; s= '12 34/n56 78/n90'<br /><br />&gt;&gt;&gt; re.findall( r'^/d+' , s , re.M )&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #匹配位于行首的数字<br /><br />['12', '56', '90']<br /><br />&gt;&gt;&gt; re.findall( r&#8217;/A/d+&#8217;, s , re.M )&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #匹配位于字符串开头的数字<br /><br />['12']<br /><br />&gt;&gt;&gt; re.findall( r'/d+$' , s , re.M )&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #匹配位于行尾的数字<br /><br />['34', '78', '90']<br /><br />&gt;&gt;&gt; re.findall( r&#8217;/d+/Z&#8217; , s , re.M )&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #匹配位于字符串尾的数字<br /><br />['90']<br /><br />&nbsp;<br /><br />&#8216;/b&#8217;匹配单词边界<br /><br />它匹配一个单词的边界，比如空格等，不过它是一个&#8216;0&#8217;长度字符，它匹配完的字符串不会包括那个分界的字符。而如果用&#8217;/s&#8217;来匹配的话，则匹配出的字符串中会包含那个<br /><br />分界符。<br /><br />例：<br /><br />&gt;&gt;&gt; s =&nbsp; 'abc abcde bc bcd'<br /><br />&gt;&gt;&gt; re.findall( r&#8217;/bbc/b&#8217; , s )&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #匹配一个单独的单词&#8216;bc&#8217; ，而当它是其它单词的一部分的时候不匹配<br /><br />['bc']&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ＃只找到了那个单独的&#8217;bc&#8217;<br /><br />&gt;&gt;&gt; re.findall( r&#8217;/sbc/s&#8217; , s )&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ＃匹配一个单独的单词&#8216;bc&#8217;&nbsp;<br /><br />[' bc ']&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #只找到那个单独的&#8217;bc&#8217;，不过注意前后有两个空格，可能有点看不清楚<br /><br />&#8216;/B&#8217;匹配非边界<br /><br />和&#8217;/b&#8217;相反，它只匹配非边界的字符。它同样是个0长度字符。<br /><br />接上例：<br /><br />&gt;&gt;&gt; re.findall( r&#8217;/Bbc/w+&#8217; , s )&nbsp;&nbsp;&nbsp;&nbsp; #匹配包含&#8217;bc&#8217;但不以&#8217;bc&#8217;为开头的单词<br /><br />['bcde']&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #成功匹配了&#8217;abcde&#8217;中的&#8217;bcde&#8217;，而没有匹配&#8217;bcd&#8217;<br /><br />&nbsp;<br /><br />&#8216;(?:)&#8217;无捕获组<br /><br />当你要将一部分规则作为一个整体对它进行某些操作，比如指定其重复次数时，你需要将这部分规则用&#8217;(?:&#8217; &#8216;)&#8217;把它包围起来，而不能仅仅只用一对括号，那样将得到绝对<br /><br />出人意料的结果。<br /><br />例：匹配字符串中重复的&#8217;ab&#8217;<br /><br />&gt;&gt;&gt; s=&#8217;ababab abbabb aabaab&#8217;<br /><br />&gt;&gt;&gt; re.findall( r&#8217;/b(?:ab)+/b&#8217; , s )<br /><br />['ababab']<br /><br />如果仅使用一对括号，看看会是什么结果：<br /><br />&gt;&gt;&gt; re.findall( r&#8217;/b(ab)+/b&#8217; , s )<br /><br />['ab']<br /><br />这是因为如果只使用一对括号，那么这就成为了一个组(group)。组的使用比较复杂，将在后面详细讲解。<br /><br />&nbsp;<br /><br />&#8216;(?# )&#8217;注释<br /><br />Python允许你在正则表达式中写入注释，在&#8217;(?#&#8217; &#8216;)&#8217;之间的内容将被忽略。<br /><br />&nbsp;<br /><br />(?iLmsux) 编译选项指定<br /><br />Python的正则式可以指定一些选项，这个选项可以写在findall或compile的参数中，也可以写在正则式里，成为正则式的一部分。这在某些情况下会便利一些。具体的选项含义请<br /><br />看后面的compile函数的说明。<br /><br />此处编译选项&#8217;i&#8217;等价于IGNORECASE ，L 等价于 LOCAL ，m 等价于 MULTILINE，s等价于 DOTALL ，u等价于UNICODE ， x 等价于 VERBOSE。<br /><br />请注意它们的大小写。在使用时可以只指定一部分，比如只指定忽略大小写，可写为&#8216;(?i)&#8217;，要同时忽略大小写并使用多行模式，可以写为&#8216;(?im)&#8217;。<br /><br />另外要注意选项的有效范围是整条规则，即写在规则的任何地方，选项都会对全部整条正则式有效。<br /><br />&nbsp;<br /><br />&nbsp;<br /><br />1.2重复<br /><br />正则式需要匹配不定长的字符串，那就一定需要表示重复的指示符。Python的正则式表示重复的功能很丰富灵活。重复规则的一般的形式是在一条字符规则后面紧跟一个表示重复<br /><br />次数的规则，已表明需要重复前面的规则一定的次数。重复规则有：<br /><br />&#8216;*&#8217;&nbsp;&nbsp; 0或多次匹配<br /><br />表示匹配前面的规则0次或多次。<br /><br />&#8216;+&#8217;&nbsp;&nbsp; 1次或多次匹配<br /><br />表示匹配前面的规则至少1次，可以多次匹配<br /><br />例：匹配以下字符串中的前一部分是字母，后一部分是数字或没有的变量名字<br /><br />&gt;&gt;&gt; s = &#8216; aaa bbb111 cc22cc 33dd &#8216;<br /><br />&gt;&gt;&gt; re.findall( r&#8217;/b[a-z]+/d*/b&#8217; , s )&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #必须至少1个字母开头，以连续数字结尾或没有数字<br /><br />['aaa', 'bbb111']<br /><br />注意上例中规则前后加了表示单词边界的&#8217;/b&#8217;指示符，如果不加的话结果就会变成：<br /><br />&gt;&gt;&gt; re.findall( r&#8217;[a-z]+/d*&#8217; , s )<br /><br />['aaa', 'bbb111', 'cc22', 'cc', 'dd']&nbsp;&nbsp;&nbsp; #把单词给拆开了<br /><br />大多数情况下这不是我们期望的结果。<br /><br />&nbsp;<br /><br />&#8216;?&#8217;&nbsp;&nbsp; 0或1次匹配<br /><br />只匹配前面的规则0次或1次。<br /><br />例，匹配一个数字，这个数字可以是一个整数，也可以是一个科学计数法记录的数字，比如123和10e3都是正确的数字。<br /><br />&gt;&gt;&gt; s = &#8216; 123 10e3 20e4e4 30ee5 &#8216;<br /><br />&gt;&gt;&gt; re.findall( r&#8217; /b/d+[eE]?/d*/b&#8217; , s )<br /><br />['123', '10e3']<br /><br />它正确匹配了123和10e3,正是我们期望的。注意前后的&#8217;/b&#8217;的使用，否则将得到不期望的结果。<br /><br />&nbsp;<br /><br />1.2.1 精确匹配和最小匹配<br /><br />Python正则式还可以精确指定匹配的次数。指定的方式是<br /><br />&#8216;{m}&#8217;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 精确匹配m次<br /><br />&#8216;{m,n}&#8217;&nbsp;&nbsp; 匹配最少m次，最多n次。(n&gt;m)<br /><br />如果你只想指定一个最少次数或只指定一个最多次数，你可以把另外一个参数空起来。比如你想指定最少3次，可以写成{3,}（注意那个逗号），同样如果只想指定最大为5次，可<br /><br />以写成{，5}，也可以写成{0,5}。<br /><br />例寻找下面字符串中<br /><br />a：3位数<br /><br />b: 2位数到4位数<br /><br />c: 5位数以上的数<br /><br />d: 4位数以下的数<br /><br />&gt;&gt;&gt; s= &#8216; 1 22 333 4444 55555 666666 &#8216;<br /><br />&gt;&gt;&gt; re.findall( r&#8217;/b/d{3}/b&#8217; , s )&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # a：3位数<br /><br />['333']<br /><br />&gt;&gt;&gt; re.findall( r&#8217;/b/d{2,4}/b&#8217; , s )&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # b: 2位数到4位数<br /><br />['22', '333', '4444']<br /><br />&gt;&gt;&gt; re.findall( r&#8217;/b/d{5,}/b&#8217;, s )&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # c: 5位数以上的数<br /><br />['55555', '666666']<br /><br />&gt;&gt;&gt; re.findall( r&#8217;/b/d{1,4}/b&#8217; , s )&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # 4位数以下的数<br /><br />['1', '22', '333', '4444']<br /><br />&nbsp;<br /><br />&#8216;*?&#8217; &#8216;+?&#8217; &#8216;??&#8217;最小匹配<br /><br />&#8216;*&#8217; &#8216;+&#8217; &#8216;?&#8217;通常都是尽可能多的匹配字符。有时候我们希望它尽可能少的匹配。比如一个c语言的注释&#8216;/* part 1 */ /* part 2 */&#8217;，如果使用最大规则：<br /><br />&gt;&gt;&gt; s =r &#8216;/* part 1 */ code /* part 2 */&#8217;<br /><br />&gt;&gt;&gt; re.findall( r&#8217;//*.*/*/&#8217; , s )<br /><br />[&#8216;/* part 1 */ code /* part 2 */&#8217;]<br /><br />结果把整个字符串都包括进去了。如果把规则改写成<br /><br />&gt;&gt;&gt; re.findall( r&#8217;//*.*?/*/&#8217; , s )&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #在*后面加上?，表示尽可能少的匹配<br /><br />['/* part 1 */', '/* part 2 */']<br /><br />结果正确的匹配出了注释里的内容<br /><br />&nbsp;<br /><br />1.3&nbsp;&nbsp; 前向界定与后向界定<br /><br />有时候需要匹配一个跟在特定内容后面的或者在特定内容前面的字符串，Python提供一个简便的前向界定和后向界定功能，或者叫前导指定和跟从指定功能。它们是：<br /><br />&#8216;(?&lt;=&#8230;)&#8217;前向界定<br /><br />括号中&#8217;&#8230;&#8217;代表你希望匹配的字符串的前面应该出现的字符串。<br /><br />&#8216;(?=&#8230;)&#8217;&nbsp; 后向界定<br /><br />括号中的&#8217;&#8230;&#8217;代表你希望匹配的字符串后面应该出现的字符串。<br /><br />例：你希望找出c语言的注释中的内容，它们是包含在&#8217;/*&#8217;和&#8217;*/&#8217;之间，不过你并不希望匹配的结果把&#8217;/*&#8217;和&#8217;*/&#8217;也包括进来，那么你可以这样用：<br /><br />&gt;&gt;&gt; s=r&#8217;/* comment 1 */&nbsp; code&nbsp; /* comment 2 */&#8217;<br /><br />&gt;&gt;&gt; re.findall( r&#8217;(?&lt;=//*).+?(?=/*/)&#8217; , s )<br /><br />[' comment 1 ', ' comment 2 ']<br /><br />注意这里我们仍然使用了最小匹配，以避免把整个字符串给匹配进去了。<br /><br />要注意的是，前向界定括号中的表达式必须是常值，也即你不可以在前向界定的括号里写正则式。比如你如果在下面的字符串中想找到被字母夹在中间的数字，你不可以用前向界<br /><br />定：<br /><br />例：<br /><br />&gt;&gt;&gt; s = &#8216;aaa111aaa , bbb222 , 333ccc &#8216;<br /><br />&gt;&gt;&gt; re.findall( r&#8217;(?&lt;=[a-z]+)/d+(?=[a-z]+)' , s )&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #错误的用法<br /><br />它会给出一个错误信息：<br /><br />error: look-behind requires fixed-width pattern<br /><br />&nbsp;<br /><br />不过如果你只要找出后面接着有字母的数字，你可以在后向界定写正则式：<br /><br />&gt;&gt;&gt; re.findall( r&#8217;/d+(?=[a-z]+)&#8217;, s )<br /><br />['111', '333']<br /><br />如果你一定要匹配包夹在字母中间的数字，你可以使用组（group）的方式<br /><br />&gt;&gt;&gt; re.findall (r'[a-z]+(/d+)[a-z]+' , s )<br /><br />['111']<br /><br />组的使用将在后面详细讲解。<br /><br />&nbsp;<br /><br />除了前向界定前向界定和后向界定外，还有前向非界定和后向非界定，它的写法为：<br /><br />&#8216;(?&lt;!...)&#8217;前向非界定<br /><br />只有当你希望的字符串前面不是&#8217;&#8230;&#8217;的内容时才匹配<br /><br />&#8216;(?!...)&#8217;后向非界定<br /><br />只有当你希望的字符串后面不跟着&#8217;&#8230;&#8217;内容时才匹配。<br /><br />接上例，希望匹配后面不跟着字母的数字<br /><br />&gt;&gt;&gt; re.findall( r&#8217;/d+(?!/w+)&#8217; , s )<br /><br />['222']<br /><br />注意这里我们使用了/w而不是像上面那样用[a-z]，因为如果这样写的话，结果会是：<br /><br />&gt;&gt;&gt; re.findall( r&#8217;/d+(?![a-z]+)&#8217; , s )<br /><br />['11', '222', '33']<br /><br />这和我们期望的似乎有点不一样。它的原因，是因为&#8217;111&#8217;和&#8217;222&#8217;中的前两个数字也是满足这个要求的。因此可看出，正则式的使用还是要相当小心的，因为我开始就是这样<br /><br />写的，看到结果后才明白过来。不过Python试验起来很方便，这也是脚本语言的一大优点，可以一步一步的试验，快速得到结果，而不用经过烦琐的编译、链接过程。也因此学习<br /><br />Python就要多试，跌跌撞撞的走过来，虽然曲折，却也很有乐趣。<br /><br />&nbsp;<br /><br />1.4组的基本知识<br /><br />上面我们已经看过了Python的正则式的很多基本用法。不过如果仅仅是上面那些规则的话，还是有很多情况下会非常麻烦，比如上面在讲前向界定和后向界定时，取夹在字母中间<br /><br />的数字的例子。用前面讲过的规则都很难达到目的，但是用了组以后就很简单了。<br /><br />&#8216;(&#8216;&#8217;)&#8217;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 无命名组<br /><br />最基本的组是由一对圆括号括起来的正则式。比如上面匹配包夹在字母中间的数字的例子中使用的(/d+)，我们再回顾一下这个例子：<br /><br />&gt;&gt;&gt; s = &#8216;aaa111aaa , bbb222 , 333ccc &#8216;<br /><br />&gt;&gt;&gt; re.findall (r'[a-z]+(/d+)[a-z]+' , s )<br /><br />['111']<br /><br />可以看到findall函数只返回了包含在&#8217;()&#8217;中的内容，而虽然前面和后面的内容都匹配成功了，却并不包含在结果中。<br /><br />&nbsp;<br /><br />除了最基本的形式外，我们还可以给组起个名字，它的形式是<br /><br />&#8216;(?P&lt;name&gt;&#8230;)&#8217;命名组<br /><br />&#8216;(?P&#8217;代表这是一个Python的语法扩展&#8217;&lt;&#8230;&gt;&#8217;里面是你给这个组起的名字，比如你可以给一个全部由数字组成的组叫做&#8217;num&#8217;，它的形式就是&#8217;(?P&lt;num&gt;/d+)&#8217;。起了名字之<br /><br />后，我们就可以在后面的正则式中通过名字调用这个组，它的形式是<br /><br />&#8216;(?P=name)&#8217;调用已匹配的命名组<br /><br />要注意，再次调用的这个组是已被匹配的组，也就是说它里面的内容是和前面命名组里的内容是一样的。<br /><br />我们可以看更多的例子：请注意下面这个字符串各子串的特点。<br /><br />&gt;&gt;&gt; s='aaa111aaa,bbb222,333ccc,444ddd444,555eee666,fff777ggg'<br /><br />我们看看下面的正则式会返回什么样的结果：<br /><br />&gt;&gt;&gt; re.findall( r'([a-z]+)/d+([a-z]+)' , s )&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #找出中间夹有数字的字母<br /><br />[('aaa', 'aaa'), ('fff', 'ggg')]<br /><br />&gt;&gt;&gt; re.findall( r '(?P&lt;g1&gt;[a-z]+)/d+(?P=g1)' , s ) #找出被中间夹有数字的前后同样的字母<br /><br />['aaa']<br /><br />&gt;&gt;&gt; re.findall( r'[a-z]+(/d+)([a-z]+)' , s )&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #找出前面有字母引导，中间是数字，后面是字母的字符串中的中间的数字和后面的字母<br /><br />[('111', 'aaa'), ('777', 'ggg')]<br /><br />&nbsp;<br /><br />我们可以通过命名组的名字在后面调用已匹配的命名组，不过名字也不是必需的。<br /><br />&#8216;/number&#8217;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 通过序号调用已匹配的组<br /><br />正则式中的每个组都有一个序号，序号是按组从左到右，从1开始的数字，你可以通过下面的形式来调用已匹配的组<br /><br />比如上面找出被中间夹有数字的前后同样的字母的例子，也可以写成：<br /><br />&gt;&gt;&gt; re.findall( r&#8217;([a-z]+)/d+/1&#8217; , s )<br /><br />['aaa']<br /><br />结果是一样的。<br /><br />我们再看一个例子<br /><br />&gt;&gt;&gt; s='111aaa222aaa111 , 333bbb444bb33'<br /><br />&gt;&gt;&gt; re.findall( r'(/d+)([a-z]+)(/d+)(/2)(/1)' , s )&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #找出完全对称的数字－字母－数字－字母－数字中的数字和字母<br /><br />[('111', 'aaa', '222', 'aaa', '111')]<br /><br />&nbsp;<br /><br />Python2.4以后的re模块，还加入了一个新的条件匹配功能<br /><br />&#8216;(?(id/name)yes-pattern|no-pattern)&#8217; 判断指定组是否已匹配，执行相应的规则<br /><br />这个规则的含义是，如果id/name指定的组在前面匹配成功了，则执行yes-pattern的正则式，否则执行no-pattern的正则式。<br /><br />举个例子，比如要匹配一些形如usr@mail的邮箱地址，不过有的写成&lt; usr@mail &gt;即用一对&lt;&gt;括起来，有点则没有，要匹配这两种情况，可以这样写<br /><br />&gt;&gt;&gt; s='&lt;usr1@mail1&gt;&nbsp; usr2@maill2'<br /><br />&gt;&gt;&gt; re.findall( r'(&lt;)?/s*(/w+@/w+)/s*(?(1)&gt;)' , s )<br /><br />[('&lt;', 'usr1@mail1'), ('', 'usr2@maill2')]<br /><br />不过如果目标字符串如下<br /><br />&gt;&gt;&gt; s='&lt;usr1@mail1&gt;&nbsp; usr2@maill2 &lt;usr3@mail3&nbsp;&nbsp; usr4@mail4&gt;&nbsp; &lt; usr5@mail5 '<br /><br />而你想得到要么由一对&lt;&gt;包围起来的一个邮件地址，要么得到一个没有被&lt;&gt;包围起来的地址，但不想得到一对&lt;&gt;中间包围的多个地址或不完整的&lt;&gt;中的地址，那么使用这个式子并<br /><br />不能得到你想要的结果<br /><br />&gt;&gt;&gt; re.findall( r'(&lt;)?/s*(/w+@/w+)/s*(?(1)&gt;)' , s )<br /><br />[('&lt;', 'usr1@mail1'), ('', 'usr2@maill2'), ('', 'usr3@mail3'), ('', 'usr4@mail4'), ('', 'usr5@mail5')]<br /><br />它仍然找到了所有的邮件地址。<br /><br />想要实现这个功能，单纯的使用findall有点吃力，需要使用其它的一些函数，比如match或search函数，再配合一些控制功能。这部分的内容将在下面详细讲解。<br /><br />&nbsp;<br /><br />小结：以上基本上讲述了Python正则式的语法规则。虽然大部分语法规则看上去都很简单，可是稍不注意，仍然会得到与期望大相径庭的结果，所以要写好正则式，需要仔细的体<br /><br />会正则式规则的含义后不同规则之间细微的差别。<br /><br />详细的了解了规则后，再配合后面就要介绍的功能函数，就能最大的发挥正则式的威力了。<br /><br />&nbsp;<br /><br />2 re模块的基本函数<br /><br />在上面的说明中，我们已经对re模块的基本函数&#8216;findall&#8217;很熟悉了。当然如果光有findall的话，很多功能是不能实现的。下面开始介绍一下re模块其它的常用基本函数。灵活<br /><br />搭配使用这些函数，才能充分发挥Python正则式的强大功能。<br /><br />首先还是说下老熟人findall函数吧<br /><br />findall(rule , target [,flag] )<br /><br />在目标字符串中查找符合规则的字符串。<br /><br />第一个参数是规则，第二个参数是目标字符串，后面还可以跟一个规则选项（选项功能将在compile函数的说明中详细说明）。<br /><br />返回结果结果是一个列表，中间存放的是符合规则的字符串。如果没有符合规则的字符串被找到，就返回一个空列表。<br /><br />2.1使用compile加速<br /><br />compile( rule [,flag] )<br /><br />将正则规则编译成一个Pattern对象，以供接下来使用。<br /><br />第一个参数是规则式，第二个参数是规则选项。<br /><br />返回一个Pattern对象<br /><br />直接使用findall ( rule , target )的方式来匹配字符串，一次两次没什么，如果是多次使用的话，由于正则引擎每次都要把规则解释一遍，而规则的解释又是相当费时间的，<br /><br />所以这样的效率就很低了。如果要多次使用同一规则来进行匹配的话，可以使用re.compile函数来将规则预编译，使用编译过返回的Regular Expression Object或叫做Pattern对<br /><br />象来进行查找。<br /><br />例<br /><br />&gt;&gt;&gt; s='111,222,aaa,bbb,ccc333,444ddd'<br /><br />&gt;&gt;&gt; rule=r&#8217;/b/d+/b&#8217;<br /><br />&gt;&gt;&gt; compiled_rule=re.compile(rule)<br /><br />&gt;&gt;&gt; compiled_rule.findall(s)<br /><br />['111', '222']<br /><br />可见使用compile过的规则使用和未编译的使用很相似。compile函数还可以指定一些规则标志，来指定一些特殊选项。多个选项之间用&#8217;|&#8217;（位或）连接起来。<br /><br />I&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IGNORECASE 忽略大小写区别。<br /><br />&nbsp;<br /><br />L&nbsp;&nbsp; LOCAL&nbsp; 字符集本地化。这个功能是为了支持多语言版本的字符集使用环境的，比如在转义符/w，在英文环境下，它代表[a-zA-Z0-9]，即所以英文字符和数字。如果在一个法<br /><br />语环境下使用，缺省设置下，不能匹配"&#233;"或"&#231;"。加上这L选项和就可以匹配了。不过这个对于中文环境似乎没有什么用，它仍然不能匹配中文字符。<br /><br />&nbsp;<br /><br />M&nbsp;&nbsp;&nbsp; MULTILINE&nbsp; 多行匹配。在这个模式下&#8217;^&#8217;(代表字符串开头)和&#8217;$&#8217;(代表字符串结尾)将能够匹配多行的情况，成为行首和行尾标记。比如<br /><br />&gt;&gt;&gt; s=&#8217;123 456/n789 012/n345 678&#8217;<br /><br />&gt;&gt;&gt; rc=re.compile(r&#8217;^/d+&#8217;)&nbsp;&nbsp;&nbsp; #匹配一个位于开头的数字，没有使用M选项<br /><br />&gt;&gt;&gt; rc.findall(s)<br /><br />['123']&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #结果只能找到位于第一个行首的&#8217;123&#8217;<br /><br />&gt;&gt;&gt; rcm=re.compile(r&#8217;^/d+&#8217;,re.M)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #使用M选项<br /><br />&gt;&gt;&gt; rcm.findall(s)<br /><br />['123', '789', '345']&nbsp; #找到了三个行首的数字<br /><br />同样，对于&#8217;$&#8217;来说，没有使用M选项，它将匹配最后一个行尾的数字，即&#8217;678&#8217;，加上以后，就能匹配三个行尾的数字456 012和678了.<br /><br />&gt;&gt;&gt; rc=re.compile(r&#8217;/d+$&#8217;)<br /><br />&gt;&gt;&gt; rcm=re.compile(r&#8217;/d+$&#8217;,re.M)<br /><br />&gt;&gt;&gt; rc.findall(s)<br /><br />['678']<br /><br />&gt;&gt;&gt; rcm.findall(s)<br /><br />['456', '012', '678']<br /><br />&nbsp;<br /><br />S&nbsp;&nbsp;&nbsp;&nbsp; DOTALL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8216;.&#8217;号将匹配所有的字符。缺省情况下&#8217;.&#8217;匹配除换行符&#8217;/n&#8217;外的所有字符，使用这一选项以后，&#8217;.&#8217;就能匹配包括&#8217;/n&#8217;的任何字符了。<br /><br />&nbsp;<br /><br />U&nbsp;&nbsp; UNICODE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /w,/W,/b,/B,/d,/D,/s和/S都将使用Unicode。<br /><br />&nbsp;<br /><br />X&nbsp;&nbsp;&nbsp;&nbsp; VERBOSE&nbsp;&nbsp;&nbsp;&nbsp; 这个选项忽略规则表达式中的空白，并允许使用&#8217;#&#8217;来引导一个注释。这样可以让你把规则写得更美观些。比如你可以把规则<br />&gt;&gt;&gt; rc = re.compile(r"/d+|[a-zA-Z]+")&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #匹配一个数字或者单词<br /><br />使用X选项写成：<br />&gt;&gt;&gt; rc = re.compile(r"""&nbsp; # start a rule/d+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # number| [a-zA-Z]+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # word""", re.VERBOSE)在这个模式下，如果你想匹配一个空格，你必须<br /><br />用'/ '的形式（'/'后面跟一个空格）<br /><br />&nbsp;<br /><br />&nbsp;<br /><br />2.2 match与search<br /><br />match( rule , targetString [,flag] )<br /><br />search( rule , targetString [,flag] )<br /><br />（注：re的match与search函数同compile过的Pattern对象的match与search函数的参数是不一样的。Pattern对象的match与search函数更为强大，是真正最常用的函数）<br /><br />按照规则在目标字符串中进行匹配。<br /><br />第一个参数是正则规则，第二个是目标字符串，第三个是选项（同compile函数的选项）<br /><br />返回：若成功返回一个Match对象，失败无返回<br /><br />findall虽然很直观，但是在进行更复杂的操作时，就有些力不从心了。此时更多的使用的是match和search函数。他们的参数和findall是一样的，都是：<br /><br />match( rule , targetString [,flag] )<br /><br />search( rule , targetString [,flag] )<br /><br />不过它们的返回不是一个简单的字符串列表，而是一个MatchObject（如果匹配成功的话）.。通过操作这个matchObject，我们可以得到更多的信息。<br /><br />需要注意的是，如果匹配不成功，它们则返回一个NoneType。所以在对匹配完的结果进行操作之前，你必需先判断一下是否匹配成功了，比如：<br /><br />&gt;&gt;&gt; m=re.match( rule , target )<br /><br />&gt;&gt;&gt; if m:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #必需先判断是否成功<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; doSomethin<br /><br />这两个函数唯一的区别是：match从字符串的开头开始匹配，如果开头位置没有匹配成功，就算失败了；而search会跳过开头，继续向后寻找是否有匹配的字符串。针对不同的需<br /><br />要，可以灵活使用这两个函数。<br /><br />关于match返回的MatchObject如果使用的问题，是Python正则式的精髓所在，它与组的使用密切相关。我将在下一部分详细讲解，这里只举个最简单的例子：<br /><br />例：<br /><br />&gt;&gt;&gt; s= 'Tom:9527 , Sharry:0003'<br /><br />&gt;&gt;&gt; m=re.match( r'(?P&lt;name&gt;/w+):(?P&lt;num&gt;/d+)' , s )<br /><br />&gt;&gt;&gt; m.group()<br /><br />'Tom:9527'<br /><br />&gt;&gt;&gt; m.groups()<br /><br />('Tom', '9527')<br /><br />&gt;&gt;&gt; m.group(&#8216;name&#8217;)<br /><br />'Tom'<br /><br />&gt;&gt;&gt; m.group(&#8216;num&#8217;)<br /><br />'9527'<br /><br />&nbsp;<br /><br />2.3 finditer<br /><br />finditer( rule , target [,flag] )<br /><br />参数同findall<br /><br />返回一个迭代器<br /><br />finditer函数和findall函数的区别是，findall返回所有匹配的字符串，并存为一个列表，而finditer则并不直接返回这些字符串，而是返回一个迭代器。关于迭代器，解释起来<br /><br />有点复杂，还是看看例子把：<br /><br />&gt;&gt;&gt; s=&#8217;111 222 333 444&#8217;<br /><br />&gt;&gt;&gt; for i in re.finditer(r&#8217;/d+&#8217; , s ):<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print i.group(),i.span()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #打印每次得到的字符串和起始结束位置<br /><br />结果是<br /><br />111 (0, 3)<br /><br />222 (4, 7)<br /><br />333 (8, 11)<br /><br />444 (12, 15)<br /><br />简单的说吧，就是finditer返回了一个可调用的对象，使用for i in finditer()的形式，可以一个一个的得到匹配返回的Match对象。这在对每次返回的对象进行比较复杂的操作<br /><br />时比较有用。<br /><br />&nbsp;<br /><br />2.4字符串的替换和修改<br /><br />re模块还提供了对字符串的替换和修改函数，他们比字符串对象提供的函数功能要强大一些。这几个函数是<br /><br />sub ( rule , replace , target [,count] )<br /><br />subn(rule , replace , target [,count] )<br /><br />在目标字符串中规格规则查找匹配的字符串，再把它们替换成指定的字符串。你可以指定一个最多替换次数，否则将替换所有的匹配到的字符串。<br /><br />第一个参数是正则规则，第二个参数是指定的用来替换的字符串，第三个参数是目标字符串，第四个参数是最多替换次数。<br /><br />这两个函数的唯一区别是返回值。<br /><br />sub返回一个被替换的字符串<br /><br />sub返回一个元组，第一个元素是被替换的字符串，第二个元素是一个数字，表明产生了多少次替换。<br /><br />例，将下面字符串中的&#8217;dog&#8217;全部替换成&#8217;cat&#8217;<br /><br />&gt;&gt;&gt; s=&#8217; I have a dog , you have a dog , he have a dog &#8216;<br /><br />&gt;&gt;&gt; re.sub( r&#8217;dog&#8217; , &#8216;cat&#8217; , s )<br /><br />' I have a cat , you have a cat , he have a cat '<br /><br />如果我们只想替换前面两个，则<br /><br />&gt;&gt;&gt; re.sub( r&#8217;dog&#8217; , &#8216;cat&#8217; , s , 2 )<br /><br />' I have a cat , you have a cat , he have a dog '<br /><br />或者我们想知道发生了多少次替换，则可以使用subn<br /><br />&gt;&gt;&gt; re.subn( r&#8217;dog&#8217; , &#8216;cat&#8217; , s )<br /><br />(' I have a cat , you have a cat , he have a cat ', 3)<br /><br />&nbsp;<br /><br />split( rule , target [,maxsplit] )<br /><br />切片函数。使用指定的正则规则在目标字符串中查找匹配的字符串，用它们作为分界，把字符串切片。<br /><br />第一个参数是正则规则，第二个参数是目标字符串，第三个参数是最多切片次数<br /><br />返回一个被切完的子字符串的列表<br /><br />这个函数和str对象提供的split函数很相似。举个例子，我们想把上例中的字符串被&#8217;,&#8217;分割开，同时要去掉逗号前后的空格<br /><br />&gt;&gt;&gt; s=&#8217; I have a dog&nbsp;&nbsp; ,&nbsp;&nbsp; you have a dog&nbsp; ,&nbsp; he have a dog &#8216;<br /><br />&gt;&gt;&gt; re.split( &#8216;/s*,/s*&#8217; , s )<br /><br />[' I have a dog', 'you have a dog', 'he have a dog ']<br /><br />结果很好。如果使用str对象的split函数，则由于我们不知道&#8217;,&#8217;两边会有多少个空格，而不得不对结果再进行一次处理。<br /><br />&nbsp;<br /><br />escape( string )<br /><br />这是个功能比较古怪的函数，它的作用是将字符串中的non-alphanumerics字符（我已不知道该怎么翻译比较好了）用反义字符的形式显示出来。有时候你可能希望在正则式中匹<br /><br />配一个字符串，不过里面含有很多re使用的符号，你要一个一个的修改写法实在有点麻烦，你可以使用这个函数,<br /><br />例在目标字符串s中匹配&#8217;(*+?)&#8217;这个子字符串<br /><br />&gt;&gt;&gt; s= &#8216;111 222 (*+?) 333&#8217;<br /><br />&gt;&gt;&gt; rule= re.escape( r&#8217;(*+?)&#8217; )<br /><br />&gt;&gt;&gt; print rule<br /><br />/(/*/+/?/)<br /><br />&gt;&gt;&gt; re.findall( rule , s )<br /><br />['(*+?)']<br /><br />3&nbsp;&nbsp;&nbsp;&nbsp; 更深入的了解re的组与对象<br /><br />前面对Python正则式的组进行了一些简单的介绍，由于还没有介绍到match对象，而组又是和match对象密切相关的，所以必须将它们结合起来介绍才能充分地说明它们的用途。<br /><br />不过再详细介绍它们之前，我觉得有必要先介绍一下将规则编译后的生成的patter对象<br /><br />3.1编译后的Pattern对象<br /><br />将一个正则式，使用compile函数编译，不仅是为了提高匹配的速度，同时还能使用一些附加的功能。编译后的结果生成一个Pattern对象，这个对象里面有很多函数，他们看起来<br /><br />和re模块的函数非常象，它同样有findall , match , search ,finditer , sub , subn , split这些函数，只不过它们的参数有些小小的不同。一般说来，re模块函数的第一个<br /><br />参数，即正则规则不再需要了，应为规则就包含在Pattern对象中了，编译选项也不再需要了，因为已经被编译过了。因此re模块中函数的这两个参数的位置，就被后面的参数取<br /><br />代了。<br /><br />findall , match , search和finditer这几个函数的参数是一样的，除了少了规则和选项两个参数外，它们又加入了另外两个参数，它们是：查找开始位置和查找结束位置，也就<br /><br />是说，现在你可以指定查找的区间，除去你不感兴趣的区间。它们现在的参数形式是：<br /><br />findall ( targetString [, startPos [,endPos] ] )<br /><br />finditer ( targetString [, startPos [,endPos] ] )<br /><br />match ( targetString [, startPos [,endPos] ] )<br /><br />search ( targetString [, startPos [,endPos] ] )<br /><br />这些函数的使用和re模块的同名函数使用完全一样。所以就不多介绍了。<br /><br />&nbsp;<br /><br />除了和re模块的函数同样的函数外，Pattern对象还多了些东西，它们是：<br /><br />flags&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 查询编译时的选项<br /><br />pattern查询编译时的规则<br /><br />groupindex规则里的组<br /><br />这几个不是函数，而是一个值。它们提供你一些规则的信息。比如下面这个例子<br /><br />&gt;&gt;&gt; p=re.compile( r'(?P&lt;word&gt;/b[a-z]+/b)|(?P&lt;num&gt;/b/d+/b)|(?P&lt;id&gt;/b[a-z_]+/w*/b)' , re.I )<br /><br />&gt;&gt;&gt; p.flags<br /><br />2<br /><br />&gt;&gt;&gt; p.pattern<br /><br />'(?P&lt;word&gt;//b[a-z]+//b)|(?P&lt;num&gt;//b//d+//b)|(?P&lt;id&gt;//b[a-z_]+//w*//b)'<br /><br />&gt;&gt;&gt; p.groupindex<br /><br />{'num': 2, 'word': 1, 'id': 3}<br /><br />我们来分析一下这个例子：这个正则式是匹配单词、或数字、或一个由字母或&#8217;_&#8217;开头，后面接字母或数字的一个ID。我们给这三种情况的规则都包入了一个命名组，分别命名<br /><br />为&#8217;word&#8217; , &#8216;num&#8217;和&#8216;id&#8217;。我们规定大小写不敏感，所以使用了编译选项&#8216;I&#8217;。<br /><br />编译以后返回的对象为p，通过p.flag我们可以查看编译时的选项，不过它显示的不是&#8217;I&#8217;，而是一个数值2。其实re.I是一个整数，2就是它的值。我们可以查看一下：<br /><br />&gt;&gt;&gt; re.I<br /><br />2<br /><br />&gt;&gt;&gt; re.L<br /><br />4<br /><br />&gt;&gt;&gt; re.M<br /><br />8<br /><br />&#8230;<br /><br />每个选项都是一个数值。<br /><br />通过p.pattern可以查看被编译的规则是什么。使用print的话会更好看一些<br /><br />&gt;&gt;&gt; print p.pattern<br /><br />(?P&lt;word&gt;/b[a-z]+/b)|(?P&lt;num&gt;/b/d+/b)|(?P&lt;id&gt;/b[a-z_]+/w*/b)<br /><br />看，和我们输入的一样。<br /><br />接下来的p.groupindex则是一个字典，它包含了规则中的所有命名组。字典的key是名字，values是组的序号。由于字典是以名字作为key，所以一个无命名的组不会出现在这里。<br /><br />&nbsp;<br /><br />&nbsp;<br /><br />3.2组与Match对象<br /><br />组与Match对象是Python正则式的重点。只有掌握了组和Match对象的使用，才算是真正学会了Python正则式。<br /><br />3.2.1 组的名字与序号<br /><br />正则式中的每个组都有一个序号，它是按定义时从左到右的顺序从1开始编号的。其实，re的正则式还有一个0号组，它就是整个正则式本身。<br /><br />我们来看个例子<br /><br />&gt;&gt;&gt; p=re.compile( r&#8217;(?P&lt;name&gt;[a-z]+)/s+(?P&lt;age&gt;/d+)/s+(?P&lt;tel&gt;/d+).*&#8217; , re.I )<br /><br />&gt;&gt;&gt; p.groupindex<br /><br />{'age': 2, 'tel': 3, 'name': 1}<br /><br />&gt;&gt;&gt; s=&#8217;Tom 24 88888888&nbsp; &lt;=&#8217;<br /><br />&gt;&gt;&gt; m=p.search(s)<br /><br />&gt;&gt;&gt; m.groups()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #看看匹配的各组的情况<br /><br />('Tom', '24', '8888888')<br /><br />&gt;&gt;&gt; m.group(&#8216;name&#8217;)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #使用组名获取匹配的字符串<br /><br />&#8216;Tom&#8217;<br /><br />&gt;&gt;&gt; m.group( 1 )&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #使用组序号获取匹配的字符串，同使用组名的效果一样<br /><br />&gt;&gt;&gt; m.group(0)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # 0组里面是什么呢？<br /><br />'Tom 24 88888888&nbsp; &lt;='<br /><br />原来0组就是整个正则式,包括没有被包围到组里面的内容。当获取0组的时候，你可以不写这个参数。m.group(0)和m.group()的效果是一样的：<br /><br />&gt;&gt;&gt; m.group()<br /><br />'Tom 24 88888888&nbsp; &lt;='<br /><br />&nbsp;<br /><br />接下来看看更多的Match对象的方法，看看我们能做些什么。<br /><br />3.2.2 Match对象的方法<br /><br />group([index|id]) 获取匹配的组，缺省返回组0,也就是全部值<br /><br />groups()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 返回全部的组<br /><br />groupdict()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 返回以组名为key，匹配的内容为values的字典<br /><br />接上例：<br /><br />&gt;&gt;&gt; m.groupindex()<br /><br />{'age': '24', 'tel': '88888888', 'name': 'Tom'}<br /><br />start( [group] )&nbsp;&nbsp;&nbsp;&nbsp; 获取匹配的组的开始位置<br /><br />end( [group] )&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 获取匹配的组的结束位置<br /><br />span( [group] )&nbsp;&nbsp;&nbsp;&nbsp; 获取匹配的组的（开始，结束）位置<br /><br />&nbsp;<br /><br />expand( template )根据一个模版用找到的内容替换模版里的相应位置<br /><br />这个功能比较有趣，它根据一个模版来用匹配到的内容替换模版中的相应位置，组成一个新的字符串返回。它使用/g&lt;index|name&gt;或/index来指示一个组。<br /><br />接上例<br /><br />&gt;&gt;&gt; m.expand(r'name is /g&lt;1&gt; , age is /g&lt;age&gt; , tel is /3')<br /><br />'name is Tom , age is 24 , tel is 88888888'<br /><br />&nbsp;<br /><br />除了以上这些函数外，Match对象还有些属性<br /><br />pos&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 搜索开始的位置参数<br /><br />endpos&nbsp; 搜索结束的位置参数<br /><br />这两个是使用findall或match等函数时，传入的参数。在上面这个例子里，我们没有指定开始和结束位置，那么缺省的开始位置就是0,结束位置就是最后。<br /><br />&gt;&gt;&gt; m.pos<br /><br />0<br /><br />&gt;&gt;&gt; m.endpos<br /><br />19<br /><br />lastindex 最后匹配的组的序号<br /><br />&gt;&gt;&gt; m.lastindex<br /><br />3<br /><br />lastgroup&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 最后匹配的组名<br /><br />&gt;&gt;&gt; m.lastgroup<br /><br />'tel'<br /><br />re&nbsp;&nbsp;&nbsp; 产生这个匹配的Pattern对象，可以认为是个逆引用<br /><br />&gt;&gt;&gt; m.re.pattern<br /><br />'(?P&lt;name&gt;[a-z]+)//s+(?P&lt;age&gt;//d+)//s+(?P&lt;tel&gt;//d+).*'<br /><br />得到了产生这个匹配的规则<br /><br />string 匹配的目标字符串<br /><br />&gt;&gt;&gt; m.string<br /><br />'Tom 24 88888888&nbsp; &lt;='<br /><br />转自:<a href="http://hi.baidu.com/yangdaming1983/item/e6a8146255a5442169105b91" style="font-family: verdana, 'courier new';">http://hi.baidu.com/yangdaming1983/item/e6a8146255a5442169105b91</a></div><img src ="http://www.blogjava.net/katsutou/aggbug/395299.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/katsutou/" target="_blank">Seraphi</a> 2013-02-11 16:28 <a href="http://www.blogjava.net/katsutou/archive/2013/02/11/395299.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转:python正则表达式:捕获组</title><link>http://www.blogjava.net/katsutou/archive/2013/02/11/395298.html</link><dc:creator>Seraphi</dc:creator><author>Seraphi</author><pubDate>Mon, 11 Feb 2013 08:26:00 GMT</pubDate><guid>http://www.blogjava.net/katsutou/archive/2013/02/11/395298.html</guid><wfw:comment>http://www.blogjava.net/katsutou/comments/395298.html</wfw:comment><comments>http://www.blogjava.net/katsutou/archive/2013/02/11/395298.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/katsutou/comments/commentRss/395298.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/katsutou/services/trackbacks/395298.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;概述1.1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;什么是捕获组捕获组就是把正则表达式中子表达式匹配的内容，保存到内存中以数字编号或显式命名的组里，方便后面引用。当然，这种引用既可以是在正则表达式内部，也可以是在正则表达式外部。捕获组有两种形式，一种是普通捕获组，另一种是命名捕获组，...&nbsp;&nbsp;<a href='http://www.blogjava.net/katsutou/archive/2013/02/11/395298.html'>阅读全文</a><img src ="http://www.blogjava.net/katsutou/aggbug/395298.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/katsutou/" target="_blank">Seraphi</a> 2013-02-11 16:26 <a href="http://www.blogjava.net/katsutou/archive/2013/02/11/395298.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转：一个不错的python文件读写的教程</title><link>http://www.blogjava.net/katsutou/archive/2013/02/10/395288.html</link><dc:creator>Seraphi</dc:creator><author>Seraphi</author><pubDate>Sun, 10 Feb 2013 15:31:00 GMT</pubDate><guid>http://www.blogjava.net/katsutou/archive/2013/02/10/395288.html</guid><wfw:comment>http://www.blogjava.net/katsutou/comments/395288.html</wfw:comment><comments>http://www.blogjava.net/katsutou/archive/2013/02/10/395288.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/katsutou/comments/commentRss/395288.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/katsutou/services/trackbacks/395288.html</trackback:ping><description><![CDATA[<h1><a id="cb_post_title_url" href="http://www.cnblogs.com/allenblogs/archive/2010/09/13/1824842.html" style="margin: 0px; padding: 0px; color: #075db3; text-decoration: initial;">Python读写文件</a></h1><div style="margin: 0px; clear: both; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; line-height: 18px; background-color: #fefef2;"></div><div style="margin: 5px 0px 0px; padding: 5px 2px 5px 5px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #fefef2;"><div id="cnblogs_post_body" style="margin: 0px; word-break: normal !important;"><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">Python读写文件<br style="margin: 0px; padding: 0px;" />1.open<br style="margin: 0px; padding: 0px;" />使用open打开文件后一定要记得调用文件对象的close()方法。比如可以用try/finally语句来确保最后能关闭文件。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">file_object = open('thefile.txt')<br style="margin: 0px; padding: 0px;" />try:<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp; all_the_text = file_object.read( )<br style="margin: 0px; padding: 0px;" />finally:<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp; file_object.close( )</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">注：不能把open语句放在try块里，因为当打开文件出现异常时，文件对象file_object无法执行close()方法。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">2.读文件<br style="margin: 0px; padding: 0px;" />读文本文件<br style="margin: 0px; padding: 0px;" />input = open('data', 'r')<br style="margin: 0px; padding: 0px;" />#第二个参数默认为r<br style="margin: 0px; padding: 0px;" />input = open('data')</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">读二进制文件<br style="margin: 0px; padding: 0px;" />input = open('data', 'rb')<br style="margin: 0px; padding: 0px;" />&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">读取所有内容<br style="margin: 0px; padding: 0px;" />file_object = open('thefile.txt')<br style="margin: 0px; padding: 0px;" />try:<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp; all_the_text = file_object.read( )<br style="margin: 0px; padding: 0px;" />finally:<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp; file_object.close( )<br style="margin: 0px; padding: 0px;" />&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">读固定字节<br style="margin: 0px; padding: 0px;" />file_object = open('abinfile', 'rb')<br style="margin: 0px; padding: 0px;" />try:<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp; while True:<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; chunk = file_object.read(100)<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if not chunk:<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do_something_with(chunk)<br style="margin: 0px; padding: 0px;" />finally:<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp; file_object.close( )<br style="margin: 0px; padding: 0px;" />&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">读每行<br style="margin: 0px; padding: 0px;" />list_of_all_the_lines = file_object.readlines( )</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">如果文件是文本文件，还可以直接遍历文件对象获取每行：</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">for line in file_object:<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp; process line<br style="margin: 0px; padding: 0px;" />&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">3.写文件<br style="margin: 0px; padding: 0px;" />写文本文件<br style="margin: 0px; padding: 0px;" />output = open('data', 'w')<br style="margin: 0px; padding: 0px;" />&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">写二进制文件<br style="margin: 0px; padding: 0px;" />output = open('data', 'wb')<br style="margin: 0px; padding: 0px;" />&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">追加写文件<br style="margin: 0px; padding: 0px;" />output = open('data', 'w+')<br style="margin: 0px; padding: 0px;" />&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">写数据<br style="margin: 0px; padding: 0px;" />file_object = open('thefile.txt', 'w')<br style="margin: 0px; padding: 0px;" />file_object.write(all_the_text)<br style="margin: 0px; padding: 0px;" />file_object.close( )<br style="margin: 0px; padding: 0px;" />&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">写入多行<br style="margin: 0px; padding: 0px;" />file_object.writelines(list_of_text_strings)</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">注意，调用writelines写入多行在性能上会比使用write一次性写入要高。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">在处理日志文件的时候，常常会遇到这样的情况：日志文件巨大，不可能一次性把整个文件读入到内存中进行处理，例如需要在一台物理内存为 2GB 的机器上处理一个 2GB 的日志文件，我们可能希望每次只处理其中 200MB 的内容。<br style="margin: 0px; padding: 0px;" />在 Python 中，内置的 File 对象直接提供了一个 readlines(sizehint) 函数来完成这样的事情。以下面的代码为例：</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">file = open('test.log', 'r')sizehint = 209715200&nbsp;&nbsp; # 200Mposition = 0lines = file.readlines(sizehint)while not file.tell() - position &lt; 0:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; position = file.tell()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lines = file.readlines(sizehint)</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">每次调用 readlines(sizehint) 函数，会返回大约 200MB 的数据，而且所返回的必然都是完整的行数据，大多数情况下，返回的数据的字节数会稍微比 sizehint 指定的值大一点（除最后一次调用 readlines(sizehint) 函数的时候）。通常情况下，Python 会自动将用户指定的 sizehint 的值调整成内部缓存大小的整数倍。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">file在python是一个特殊的类型，它用于在python程序中对外部的文件进行操作。在python中一切都是对象，file也不例外，file有file的方法和属性。下面先来看如何创建一个file对象：</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;"><br style="margin: 0px; padding: 0px;" />file(name[, mode[, buffering]])&nbsp;<br style="margin: 0px; padding: 0px;" />file()函数用于创建一个file对象，它有一个别名叫open()，可能更形象一些，它们是内置函数。来看看它的参数。它参数都是以字符串的形式传递的。name是文件的名字。<br style="margin: 0px; padding: 0px;" />mode是打开的模式，可选的值为r w a U，分别代表读（默认） 写 添加支持各种换行符的模式。用w或a模式打开文件的话，如果文件不存在，那么就自动创建。此外，用w模式打开一个已经存在的文件时，原有文件的内容会被清空，因为一开始文件的操作的标记是在文件的开头的，这时候进行写操作，无疑会把原有的内容给抹掉。由于历史的原因，换行符在不同的系统中有不同模式，比如在 unix中是一个\n，而在windows中是&#8216;\r\n&#8217;，用U模式打开文件，就是支持所有的换行模式，也就说&#8216;\r&#8217; '\n' '\r\n'都可表示换行，会有一个tuple用来存贮这个文件中用到过的换行符。不过，虽说换行有多种模式，读到python中统一用\n代替。在模式字符的后面，还可以加上+ b t这两种标识，分别表示可以对文件同时进行读写操作和用二进制模式、文本模式（默认）打开文件。<br style="margin: 0px; padding: 0px;" />buffering如果为0表示不进行缓冲;如果为1表示进行&#8220;行缓冲&#8220;;如果是一个大于1的数表示缓冲区的大小，应该是以字节为单位的。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">file对象有自己的属性和方法。先来看看file的属性。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;"><br style="margin: 0px; padding: 0px;" />closed #标记文件是否已经关闭，由close()改写&nbsp;<br style="margin: 0px; padding: 0px;" />encoding #文件编码&nbsp;<br style="margin: 0px; padding: 0px;" />mode #打开模式&nbsp;<br style="margin: 0px; padding: 0px;" />name #文件名&nbsp;<br style="margin: 0px; padding: 0px;" />newlines #文件中用到的换行模式，是一个tuple&nbsp;<br style="margin: 0px; padding: 0px;" />softspace #boolean型，一般为0，据说用于print</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">file的读写方法：</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;"><br style="margin: 0px; padding: 0px;" />F.read([size]) #size为读取的长度，以byte为单位&nbsp;<br style="margin: 0px; padding: 0px;" />F.readline([size])&nbsp;<br style="margin: 0px; padding: 0px;" />#读一行，如果定义了size，有可能返回的只是一行的一部分&nbsp;<br style="margin: 0px; padding: 0px;" />F.readlines([size])&nbsp;<br style="margin: 0px; padding: 0px;" />#把文件每一行作为一个list的一个成员，并返回这个list。其实它的内部是通过循环调用readline()来实现的。如果提供size参数，size是表示读取内容的总长，也就是说可能只读到文件的一部分。&nbsp;<br style="margin: 0px; padding: 0px;" />F.write(str)&nbsp;<br style="margin: 0px; padding: 0px;" />#把str写到文件中，write()并不会在str后加上一个换行符&nbsp;<br style="margin: 0px; padding: 0px;" />F.writelines(seq)&nbsp;<br style="margin: 0px; padding: 0px;" />#把seq的内容全部写到文件中。这个函数也只是忠实地写入，不会在每行后面加上任何东西。&nbsp;<br style="margin: 0px; padding: 0px;" />file的其他方法：</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;"><br style="margin: 0px; padding: 0px;" />F.close()&nbsp;<br style="margin: 0px; padding: 0px;" />#关闭文件。python会在一个文件不用后自动关闭文件，不过这一功能没有保证，最好还是养成自己关闭的习惯。如果一个文件在关闭后还对其进行操作会产生ValueError&nbsp;<br style="margin: 0px; padding: 0px;" />F.flush()&nbsp;<br style="margin: 0px; padding: 0px;" />#把缓冲区的内容写入硬盘&nbsp;<br style="margin: 0px; padding: 0px;" />F.fileno()&nbsp;<br style="margin: 0px; padding: 0px;" />#返回一个长整型的&#8221;文件标签&#8220;&nbsp;<br style="margin: 0px; padding: 0px;" />F.isatty()&nbsp;<br style="margin: 0px; padding: 0px;" />#文件是否是一个终端设备文件（unix系统中的）&nbsp;<br style="margin: 0px; padding: 0px;" />F.tell()&nbsp;<br style="margin: 0px; padding: 0px;" />#返回文件操作标记的当前位置，以文件的开头为原点&nbsp;<br style="margin: 0px; padding: 0px;" />F.next()&nbsp;<br style="margin: 0px; padding: 0px;" />#返回下一行，并将文件操作标记位移到下一行。把一个file用于for ... in file这样的语句时，就是调用next()函数来实现遍历的。&nbsp;<br style="margin: 0px; padding: 0px;" />F.seek(offset[,whence])&nbsp;<br style="margin: 0px; padding: 0px;" />#将文件打操作标记移到offset的位置。这个offset一般是相对于文件的开头来计算的，一般为正数。但如果提供了whence参数就不一定了，whence可以为0表示从头开始计算，1表示以当前位置为原点计算。2表示以文件末尾为原点进行计算。需要注意，如果文件以a或a+的模式打开，每次进行写操作时，文件操作标记会自动返回到文件末尾。&nbsp;<br style="margin: 0px; padding: 0px;" />F.truncate([size])&nbsp;<br style="margin: 0px; padding: 0px;" />#把文件裁成规定的大小，默认的是裁到当前文件操作标记的位置。如果size比文件的大小还要大，依据系统的不同可能是不改变文件，也可能是用0把文件补到相应的大小，也可能是以一些随机的内容加上去。<br /><br /><br />本文来自CSDN博客，转载请标明出处：<a href="http://blog.csdn.net/adupt/archive/2009/08/11/4435615.aspx" style="margin: 0px; padding: 0px; color: #075db3;">http://blog.csdn.net/adupt/archive/2009/08/11/4435615.aspx</a></p></div></div><img src ="http://www.blogjava.net/katsutou/aggbug/395288.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/katsutou/" target="_blank">Seraphi</a> 2013-02-10 23:31 <a href="http://www.blogjava.net/katsutou/archive/2013/02/10/395288.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>python脚本图解，非常适合刚入门学python的人</title><link>http://www.blogjava.net/katsutou/archive/2013/02/02/395049.html</link><dc:creator>Seraphi</dc:creator><author>Seraphi</author><pubDate>Sat, 02 Feb 2013 08:01:00 GMT</pubDate><guid>http://www.blogjava.net/katsutou/archive/2013/02/02/395049.html</guid><wfw:comment>http://www.blogjava.net/katsutou/comments/395049.html</wfw:comment><comments>http://www.blogjava.net/katsutou/archive/2013/02/02/395049.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/katsutou/comments/commentRss/395049.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/katsutou/services/trackbacks/395049.html</trackback:ping><description><![CDATA[<img src="http://www.blogjava.net/images/blogjava_net/katsutou/coffeeghost-q-in-py_zh.png" width="800" height="599" alt="" /><img src ="http://www.blogjava.net/katsutou/aggbug/395049.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/katsutou/" target="_blank">Seraphi</a> 2013-02-02 16:01 <a href="http://www.blogjava.net/katsutou/archive/2013/02/02/395049.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>