<?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>I am LAZY bones ? &#187; 编程相关</title>
	<atom:link href="http://luy.li/category/programme/feed/" rel="self" type="application/rss+xml" />
	<link>http://luy.li</link>
	<description>all linux</description>
	<lastBuildDate>Mon, 30 Aug 2010 01:26:21 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>设置python的stdout为无缓存模式</title>
		<link>http://luy.li/2010/08/29/pythonunbuffered/</link>
		<comments>http://luy.li/2010/08/29/pythonunbuffered/#comments</comments>
		<pubDate>Sun, 29 Aug 2010 13:52:01 +0000</pubDate>
		<dc:creator>bones7456</dc:creator>
				<category><![CDATA[编程相关]]></category>

		<guid isPermaLink="false">http://luy.li/?p=1686</guid>
		<description><![CDATA[考虑以下python程序： #!/usr/bin/env python &#160; import sys &#160; sys.stdout.write&#40;&#34;stdout1 &#34;&#41; sys.stderr.write&#40;&#34;stderr1 &#34;&#41; sys.stdout.write&#40;&#34;stdout2 &#34;&#41; sys.stderr.write&#40;&#34;stderr2 &#34;&#41; 其中的sys.stdout.write也可以换成print。 运行这程序，你觉得会输出什么？试验一下，就会发现，其实输出并不是 stdout1 stderr1 stdout2 stderr2 而是： stderr1 stderr2 stdout1 stdout2 究其原因，是因为缓存：虽然stderr和stdout默认都是指向屏幕的，但是stderr是无缓存的，程序往stderr输出一个字符，就会在屏幕上显示一个；而stdout是有缓存的，只有遇到换行或者积累到一定的大小，才会显示出来。这就是为什么上面的会显示两个stderr的原因了。 然而，有时候，你可能还是希望stdout的行为和stderr一样，能不能实现呢？当然是可以的，而且对于python，实现起来还特别方便，以下是两个方法： python -u stderr_stdout.py PYTHONUNBUFFERED=1 python stderr_stdout.py 第一种方法是给python指定 -u 参数，第二种方法是在python运行时，指定 PYTHONUNBUFFERED 环境变量，这两种方法其实是等效的。 当然，也可以在程序的第一行指定 #!/usr/bin/python -u 然后程序加可执行权限来运行，或者把 export PYTHONUNBUFFERED=1 写到 .bashrc 里去。]]></description>
			<content:encoded><![CDATA[<p>考虑以下python程序：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
&nbsp;
<span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;stdout1 &quot;</span><span style="color: black;">&#41;</span>
<span style="color: #dc143c;">sys</span>.<span style="color: black;">stderr</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;stderr1 &quot;</span><span style="color: black;">&#41;</span>
<span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;stdout2 &quot;</span><span style="color: black;">&#41;</span>
<span style="color: #dc143c;">sys</span>.<span style="color: black;">stderr</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;stderr2 &quot;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>其中的sys.stdout.write也可以换成print。<br />
运行这程序，你觉得会输出什么？试验一下，就会发现，其实输出并不是</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">stdout1 stderr1  stdout2 stderr2</pre></div></div>

<p>而是：</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">stderr1 stderr2 stdout1  stdout2</pre></div></div>

<p>究其原因，是因为缓存：虽然stderr和stdout默认都是指向屏幕的，但是stderr是无缓存的，程序往stderr输出一个字符，就会在屏幕上显示一个；而stdout是有缓存的，只有遇到换行或者积累到一定的大小，才会显示出来。这就是为什么上面的会显示两个stderr的原因了。<br />
然而，有时候，你可能还是希望stdout的行为和stderr一样，能不能实现呢？当然是可以的，而且对于python，实现起来还特别方便，以下是两个方法：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">python <span style="color: #660033;">-u</span> stderr_stdout.py</pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #007800;">PYTHONUNBUFFERED</span>=<span style="color: #000000;">1</span> python stderr_stdout.py</pre></div></div>

<p>第一种方法是给python指定 -u 参数，第二种方法是在python运行时，指定 <code>PYTHONUNBUFFERED</code> 环境变量，这两种方法其实是等效的。<br />
当然，也可以在程序的第一行指定 #!/usr/bin/python -u 然后程序加可执行权限来运行，或者把 export PYTHONUNBUFFERED=1 写到 .bashrc 里去。</p>
]]></content:encoded>
			<wfw:commentRss>http://luy.li/2010/08/29/pythonunbuffered/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>为什么python里要 if __name__ == &#8216;__main__&#8217;:</title>
		<link>http://luy.li/2010/05/31/python__name__main__/</link>
		<comments>http://luy.li/2010/05/31/python__name__main__/#comments</comments>
		<pubDate>Mon, 31 May 2010 10:52:14 +0000</pubDate>
		<dc:creator>bones7456</dc:creator>
				<category><![CDATA[编程相关]]></category>

		<guid isPermaLink="false">http://li2z.cn/?p=1581</guid>
		<description><![CDATA[尽管python允许你像shell脚本一样，把大段的代码堆积着写，但是，很多python入门的书，都会建议你把代码写成一个函数，然后在最后面统一调用，例如这样： def main&#40;&#41;: #具体代码 &#160; if __name__ == '__main__': main&#40;&#41; 很多文章都会说这个是由于代码风格之类的原因，但是其实，不这样写，有时候也是会直接导致出错的。 举个例子，打开《A Byte of Python》的类变量那节，可以这里看在线版本，然后把中间的那示例代码复制下来，运行，可以看到，确实能得到预期正确的结果。 但是，现在把那代码里的所有“swaroop”换成“xxx1”，再把所有“kalam”换成“yyy1”，再运行，就会在程序运行的最后时刻，得到这么一个奇怪的错误（Python 2.6.5下实验）： Exception AttributeError: "'NoneType' object has no attribute 'population'" in ignored 也就是说，换了个变量名，程序就出错了。。。 究其原因，应该是python在最后析构所有类和对象的时候，并没有处理这些对象之间的依赖关系，而是根据变量名来决定某种顺序操作了。从而导致Person类本身，先于yyy2被干掉了，所以在解构yyy2的时候，执行它的__del__()方法，却发现父类都已经没有了~~ 这应该确实算是python解析器的bug，但是，如果那把这个例子里的所有class Person以外的代码，写到一个main()函数里，再通过上述方法调用的话，就不会发生这种错误了。 所以，大家最好还是别太在意多几行代码，养成这个好习惯吧。 要深究此错误的原因，可以看官方文档里的描述，并在这里讨论。]]></description>
			<content:encoded><![CDATA[<p>尽管python允许你像shell脚本一样，把大段的代码堆积着写，但是，很多python入门的书，都会建议你把代码写成一个函数，然后在最后面统一调用，例如这样：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #808080; font-style: italic;">#具体代码</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>:
    main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>很多文章都会说这个是由于代码风格之类的原因，但是其实，不这样写，有时候也是会直接导致出错的。<br />
举个例子，打开《A Byte of Python》的类变量那节，可以<a href="http://www.ibiblio.org/swaroopch/byteofpython/read/class-and-object-vars.html">这里看在线版本</a>，然后把中间的那示例代码复制下来，运行，可以看到，确实能得到预期正确的结果。<br />
但是，现在把那代码里的所有“swaroop”换成“xxx1”，再把所有“kalam”换成“yyy1”，再运行，就会在程序运行的最后时刻，得到这么一个奇怪的错误（Python 2.6.5下实验）：<br />
<code>Exception AttributeError: "'NoneType' object has no attribute 'population'" in <bound method Person.__del__ of <__main__.Person instance at 0xb689090c>> ignored</code><br />
也就是说，换了个变量名，程序就出错了。。。<br />
究其原因，应该是python在最后析构所有类和对象的时候，并没有处理这些对象之间的依赖关系，而是根据变量名来决定某种顺序操作了。从而导致<code>Person</code>类本身，先于<code>yyy2</code>被干掉了，所以在解构<code>yyy2</code>的时候，执行它的<code>__del__()</code>方法，却发现父类都已经没有了~~<br />
这应该确实算是python解析器的bug，但是，如果那把这个例子里的所有class Person以外的代码，写到一个<code>main()</code>函数里，再通过上述方法调用的话，就不会发生这种错误了。<br />
所以，大家最好还是别太在意多几行代码，养成这个好习惯吧。</p>
<p>要深究此错误的原因，可以看官方文档里的<a href="http://docs.python.org/c-api/init.html#Py_Finalize">描述</a>，并在<a href="http://groups.google.com/group/python-cn/browse_thread/thread/31df4e6076782599">这里</a>讨论。</p>
]]></content:encoded>
			<wfw:commentRss>http://luy.li/2010/05/31/python__name__main__/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>python中的socket代理</title>
		<link>http://luy.li/2010/05/20/python_socks/</link>
		<comments>http://luy.li/2010/05/20/python_socks/#comments</comments>
		<pubDate>Thu, 20 May 2010 11:21:31 +0000</pubDate>
		<dc:creator>bones7456</dc:creator>
				<category><![CDATA[编程相关]]></category>

		<guid isPermaLink="false">http://li2z.cn/?p=1570</guid>
		<description><![CDATA[说socket代理之前，先来说说http代理，python的urllib2是自带http代理功能的，可以用如下代码实现： proxy_handler = urllib2.ProxyHandler&#40;&#123;'http' : 'http://地址:端口'&#125;&#41; opener = urllib2.build_opener&#40;proxy_handler, urllib2.HTTPHandler&#41; urllib2.install_opener&#40;opener&#41; 如此，接下来用urllib2来urlopen的时候，就会自动使用这个代理了。 但是，在我们疯狂的天朝，有时候，http代理并不能满足要求，也许你还想使用更底层的socket代理，于是python里似乎就没有直接的方法了（python3不知道有没有内置，未研究）。这时候，你可能需要这个包：SocksiPy &#8211; A Python SOCKS module，下载解压以后，除了文档也就一个 socks.py 文件，很方便使用，给出示例代码： import socks, socket socks.setdefaultproxy&#40;socks.PROXY_TYPE_SOCKS5, &#34;地址&#34;, 端口&#41; socket.socket = socks.socksocket 接下来，你就可以照常使用socket了，一切都会悄悄地通过代理出去的~]]></description>
			<content:encoded><![CDATA[<p>说socket代理之前，先来说说http代理，python的urllib2是自带http代理功能的，可以用如下代码实现：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">proxy_handler = <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">ProxyHandler</span><span style="color: black;">&#40;</span><span style="color: black;">&#123;</span><span style="color: #483d8b;">'http'</span> : <span style="color: #483d8b;">'http://地址:端口'</span><span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
opener = <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">build_opener</span><span style="color: black;">&#40;</span>proxy_handler, <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">HTTPHandler</span><span style="color: black;">&#41;</span>
<span style="color: #dc143c;">urllib2</span>.<span style="color: black;">install_opener</span><span style="color: black;">&#40;</span>opener<span style="color: black;">&#41;</span></pre></div></div>

<p>如此，接下来用urllib2来urlopen的时候，就会自动使用这个代理了。</p>
<p>但是，在我们疯狂的天朝，有时候，http代理并不能满足要求，也许你还想使用更底层的socket代理，于是python里似乎就没有直接的方法了（python3不知道有没有内置，未研究）。这时候，你可能需要这个包：<a href="http://sourceforge.net/projects/socksipy/">SocksiPy</a> &#8211; A Python SOCKS module，下载解压以后，除了文档也就一个 socks.py 文件，很方便使用，给出示例代码：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> socks, <span style="color: #dc143c;">socket</span>
socks.<span style="color: black;">setdefaultproxy</span><span style="color: black;">&#40;</span>socks.<span style="color: black;">PROXY_TYPE_SOCKS5</span>, <span style="color: #483d8b;">&quot;地址&quot;</span>, 端口<span style="color: black;">&#41;</span>
<span style="color: #dc143c;">socket</span>.<span style="color: #dc143c;">socket</span> = socks.<span style="color: black;">socksocket</span></pre></div></div>

<p>接下来，你就可以照常使用socket了，一切都会悄悄地通过代理出去的~</p>
]]></content:encoded>
			<wfw:commentRss>http://luy.li/2010/05/20/python_socks/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>python的正则表达式 re</title>
		<link>http://luy.li/2010/05/12/python-re/</link>
		<comments>http://luy.li/2010/05/12/python-re/#comments</comments>
		<pubDate>Wed, 12 May 2010 06:54:59 +0000</pubDate>
		<dc:creator>bones7456</dc:creator>
				<category><![CDATA[精华]]></category>
		<category><![CDATA[编程相关]]></category>

		<guid isPermaLink="false">http://li2z.cn/?p=1491</guid>
		<description><![CDATA[延伸阅读：python的 内建函数 和 subprocess 。此文是本系列的第三篇文章了，和之前一样，内容出自官方文档，但是会有自己的理解，并非单纯的翻译。所以，如果我理解有误，欢迎指正，谢谢。 本模块提供了和Perl里的正则表达式类似的功能，不关是正则表达式本身还是被搜索的字符串，都可以是Unicode字符，这点不用担心，python会处理地和Ascii字符一样漂亮。 正则表达式使用反斜杆（\）来转义特殊字符，使其可以匹配字符本身，而不是指定其他特殊的含义。这可能会和python字面意义上的字符串转义相冲突，这也许有些令人费解。比如，要匹配一个反斜杆本身，你也许要用'\\\\'来做为正则表达式的字符串，因为正则表达式要是\\，而字符串里，每个反斜杆都要写成\\。 你也可以在字符串前加上 r 这个前缀来避免部分疑惑，因为 r 开头的python字符串是 raw 字符串，所以里面的所有字符都不会被转义，比如r'\n'这个字符串就是一个反斜杆加上一字母n，而'\n'我们知道这是个换行符。因此，上面的'\\\\'你也可以写成r'\\'，这样，应该就好理解很多了。可以看下面这段： &#62;&#62;&#62; import re &#62;&#62;&#62; s = '\x5c' #0x5c就是反斜杆 &#62;&#62;&#62; print s \ &#62;&#62;&#62; re.match&#40;'\\\\', s&#41; #这样可以匹配 &#60;_sre.SRE_Match object at 0xb6949e20&#62; &#62;&#62;&#62; re.match&#40;r'\\', s&#41; #这样也可以 &#60;_sre.SRE_Match object at 0x80ce2c0&#62; &#62;&#62;&#62; re.match&#40;'\\', s&#41; #但是这样不行 Traceback &#40;most recent call last&#41;: File &#34;&#60;stdin&#62;&#34;, line 1, [...]]]></description>
			<content:encoded><![CDATA[<p>延伸阅读：python的 <a href="http://luy.li/2009/11/29/python-built-in-functions/">内建函数</a> 和 <a href="http://luy.li/2010/04/14/python_subprocess/">subprocess</a> 。此文是本系列的第三篇文章了，和之前一样，内容出自<a href="http://docs.python.org/library/re.html">官方文档</a>，但是会有自己的理解，并非单纯的翻译。所以，如果我理解有误，欢迎指正，谢谢。</p>
<p>本模块提供了和Perl里的正则表达式类似的功能，不关是正则表达式本身还是被搜索的字符串，都可以是Unicode字符，这点不用担心，python会处理地和Ascii字符一样漂亮。<br />
正则表达式使用反斜杆（<code>\</code>）来转义特殊字符，使其可以匹配字符本身，而不是指定其他特殊的含义。这可能会和python字面意义上的字符串转义相冲突，这也许有些令人费解。比如，要匹配一个反斜杆本身，你也许要用<code>'\\\\'</code>来做为正则表达式的字符串，因为正则表达式要是<code>\\</code>，而字符串里，每个反斜杆都要写成<code>\\</code>。<br />
你也可以在字符串前加上 r 这个前缀来避免部分疑惑，因为 r 开头的python字符串是 raw 字符串，所以里面的所有字符都不会被转义，比如<code>r'\n'</code>这个字符串就是一个反斜杆加上一字母n，而<code>'\n'</code>我们知道这是个换行符。因此，上面的<code>'\\\\'</code>你也可以写成<code>r'\\'</code>，这样，应该就好理解很多了。可以看下面这段：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">re</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> s = <span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\x</span>5c'</span>  <span style="color: #808080; font-style: italic;">#0x5c就是反斜杆</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span> s
\
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">match</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\\</span><span style="color: #000099; font-weight: bold;">\\</span>'</span>, s<span style="color: black;">&#41;</span>  <span style="color: #808080; font-style: italic;">#这样可以匹配</span>
<span style="color: #66cc66;">&lt;</span>_sre.<span style="color: black;">SRE_Match</span> <span style="color: #008000;">object</span> at 0xb6949e20<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">match</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\\</span>'</span>, s<span style="color: black;">&#41;</span>  <span style="color: #808080; font-style: italic;">#这样也可以</span>
<span style="color: #66cc66;">&lt;</span>_sre.<span style="color: black;">SRE_Match</span> <span style="color: #008000;">object</span> at 0x80ce2c0<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">match</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\\</span>'</span>, s<span style="color: black;">&#41;</span>  <span style="color: #808080; font-style: italic;">#但是这样不行</span>
Traceback <span style="color: black;">&#40;</span>most recent call last<span style="color: black;">&#41;</span>:
  File <span style="color: #483d8b;">&quot;&lt;stdin&gt;&quot;</span>, line <span style="color: #ff4500;">1</span>, <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #66cc66;">&lt;</span>module<span style="color: #66cc66;">&gt;</span>
  File <span style="color: #483d8b;">&quot;/usr/lib/python2.6/re.py&quot;</span>, line <span style="color: #ff4500;">137</span>, <span style="color: #ff7700;font-weight:bold;">in</span> match
    <span style="color: #ff7700;font-weight:bold;">return</span> _compile<span style="color: black;">&#40;</span>pattern, flags<span style="color: black;">&#41;</span>.<span style="color: black;">match</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">string</span><span style="color: black;">&#41;</span>
  File <span style="color: #483d8b;">&quot;/usr/lib/python2.6/re.py&quot;</span>, line <span style="color: #ff4500;">245</span>, <span style="color: #ff7700;font-weight:bold;">in</span> _compile
    <span style="color: #ff7700;font-weight:bold;">raise</span> error, v <span style="color: #808080; font-style: italic;"># invalid expression</span>
sre_constants.<span style="color: black;">error</span>: bogus escape <span style="color: black;">&#40;</span>end of line<span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span></pre></div></div>

<p>另外值得一提的是，re模块的方法，大多也就是RegexObject对象的方法，两者的区别在于执行效率。这个在最后再展开吧。</p>
<p><big><strong>正则表达式语法</strong></big></p>
<p>正则表达式（RE）指定一个与之匹配的字符集合；本模块所提供的函数，将可以用来检查所给的字符串是否与指定的正则表达式匹配。<br />
正则表达式可以被连接，从而形成新的正则表达式；例如A和B都是正则表达式，那么AB也是正则表达式。一般地，如果字符串<em>p</em>与A匹配，<em>q</em>与B匹配的话，那么字符串<em>pq</em>也会与AB匹配，但A或者B里含有边界限定条件或者命名组操作的情况除外。也就是说，复杂的正则表达式可以用简单的连接而成。<br />
正则表达式可以包含特殊字符和普通字符，大部分字符比如<code>'A'</code>，<code>'a'</code>和<code>'0'</code>都是普通字符，如果做为正则表达式，它们将匹配它们本身。由于正则表达式可以连接，所以连接多个普通字符而成的正则表达式<code>last</code>也将匹配<code>'last'</code>。（后面将用不带引号的表示正则表达式，带引号的表示字符串）</p>
<p>下面就来介绍正则表达式的特殊字符：</p>
<p><code>'.'</code><br />
点号，在普通模式，它匹配除换行符外的任意一个字符；如果指定了 <strong>DOTALL</strong> 标记，匹配包括换行符以内的任意一个字符。</p>
<p><code>'^'</code><br />
尖尖号，匹配一个字符串的开始，在 <strong>MULTILINE</strong> 模式下，也将匹配任意一个新行的开始。</p>
<p><code>'$'</code><br />
美元符号，匹配一个字符串的结尾或者字符串最后面的换行符，在 <strong>MULTILINE</strong> 模式下，也匹配任意一行的行尾。也就是说，普通模式下，<code>foo.$</code>去搜索<code>'foo1\nfoo2\n'</code>只会找到&#8217;foo2&#8242;，但是在 <strong>MULTILINE</strong> 模式，还能找到 &#8216;foo1&#8242;，而且就用一个 <code>$</code> 去搜索<code>'foo\n'</code>的话，会找到两个空的匹配：一个是最后的换行符，一个是字符串的结尾，演示：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">findall</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'(foo.$)'</span>, <span style="color: #483d8b;">'foo1<span style="color: #000099; font-weight: bold;">\n</span>foo2<span style="color: #000099; font-weight: bold;">\n</span>'</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#91;</span><span style="color: #483d8b;">'foo2'</span><span style="color: black;">&#93;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">findall</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'(foo.$)'</span>, <span style="color: #483d8b;">'foo1<span style="color: #000099; font-weight: bold;">\n</span>foo2<span style="color: #000099; font-weight: bold;">\n</span>'</span>, <span style="color: #dc143c;">re</span>.<span style="color: black;">MULTILINE</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#91;</span><span style="color: #483d8b;">'foo1'</span>, <span style="color: #483d8b;">'foo2'</span><span style="color: black;">&#93;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">findall</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'($)'</span>, <span style="color: #483d8b;">'foo<span style="color: #000099; font-weight: bold;">\n</span>'</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#91;</span><span style="color: #483d8b;">''</span>, <span style="color: #483d8b;">''</span><span style="color: black;">&#93;</span></pre></div></div>

<p><code>'*'</code><br />
星号，指定将前面的RE重复0次或者任意多次，而且总是试图尽量多次地匹配。</p>
<p><code>'+'</code><br />
加号，指定将前面的RE重复1次或者任意多次，而且总是试图尽量多次地匹配。</p>
<p><code>'?'</code><br />
问号，指定将前面的RE重复0次或者1次，如果有的话，也尽量匹配1次。</p>
<p><code>*?</code>， <code>+?</code>， <code>??</code><br />
从前面的描述可以看到<code>'*'</code>，<code>'+'</code>和<code>'?'</code>都是<em>贪婪的</em>，但这也许并不是我们说要的，所以，可以在后面加个问号，将策略改为<em>非贪婪</em>，只匹配尽量少的RE。示例，体会两者的区别：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">findall</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'&lt;(.*)&gt;'</span>, <span style="color: #483d8b;">'&lt;H1&gt;title&lt;/H1&gt;'</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#91;</span><span style="color: #483d8b;">'H1&gt;title&lt;/H1'</span><span style="color: black;">&#93;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">findall</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'&lt;(.*?)&gt;'</span>, <span style="color: #483d8b;">'&lt;H1&gt;title&lt;/H1&gt;'</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#91;</span><span style="color: #483d8b;">'H1'</span>, <span style="color: #483d8b;">'/H1'</span><span style="color: black;">&#93;</span></pre></div></div>

<p><code>{m}</code><br />
m是一个数字，指定将前面的RE重复m次。</p>
<p><code>{m,n}</code><br />
m和n都是数字，指定将前面的RE重复m到n次，例如<code>a{3,5}</code>匹配3到5个连续的a。注意，如果省略m，将匹配0到n个前面的RE；如果省略n，将匹配n到无穷多个前面的RE；当然中间的逗号是不能省略的，不然就变成前面那种形式了。</p>
<p><code>{m,n}?</code><br />
前面说的<code>{m,n}</code>，也是贪婪的，<code>a{3,5}</code>如果有5个以上连续a的话，会匹配5个，这个也可以通过加问号改变。<code>a{3,5}?</code>如果可能的话，将只匹配3个a。</p>
<p><code>'\'</code><br />
反斜杆，转义<code>'*'</code>，<code>'?'</code>等特殊字符，或者指定一个特殊序列（下面会详述）<br />
由于之前所述的原因，强烈建议用raw字符串来表述正则。</p>
<p><code>[]</code><br />
方括号，用于指定一个字符的集合。可以单独列出字符，也可以用<code>'-'</code>连接起止字符以表示一个范围。特殊字符在中括号里将失效，比如<code>[akm$]</code>就表示字符<code>'a'</code>，<code>'k'</code>，<code>'m'</code>，或<code>'$'</code>，在这里$也变身为普通字符了。<code>[a-z]</code>匹配任意一个小写字母，<code>[a-zA-Z0-9]</code>匹配任意一个字母或数字。如果你要匹配<code>']'</code>或<code>'-'</code>本身，你需要加反斜杆转义，或者是将其置于中括号的最前面，比如<code>[]]</code>可以匹配<code>']'</code><br />
你还可以对一个字符集合<em>取反</em>，以匹配任意不在这个字符集合里的字符，<code>取反</code>操作用一个<code>'^'</code>放在集合的最前面表示，放在其他地方的<code>'^'</code>将不会起特殊作用。例如<code>[^5]</code>将匹配任意不是<code>'5'</code>的字符；<code>[^^]</code>将匹配任意不是<code>'^'</code>的字符。<br />
注意：在中括号里，<code>+</code>、<code>*</code>、<code>(</code>、<code>)</code>这类字符将会失去特殊含义，仅作为普通字符。反向引用也不能在中括号内使用。</p>
<p><code>'|'</code><br />
管道符号，A和B是任意的RE，那么<code>A|B</code>就是匹配A或者B的一个新的RE。任意个数的RE都可以像这样用管道符号间隔连接起来。这种形式可以被用于<strong>组</strong>中（后面将详述）。对于目标字符串，被<code>'|'</code>分割的RE将自左至右一一被测试，一旦有一个测试成功，后面的将不再被测试，即使后面的RE可能可以匹配更长的串，换句话说，<code>'|'</code>操作符是非贪婪的。要匹配字面意义上的<code>'|'</code>，可以用反斜杆转义：<code>\|</code>，或是包含在反括号内：<code>[|]</code>。</p>
<p><code>(...)</code><br />
匹配圆括号里的RE匹配的内容，并指定<strong>组</strong>的开始和结束位置。组里面的内容可以被提取，也可以采用<code>\number</code>这样的特殊序列，被用于后续的匹配。要匹配字面意义上的<code>'('</code>和<code>')'</code>，可以用反斜杆转义：<code>\(</code>、<code>\)</code>，或是包含在反括号内：<code>[(]</code>、<code>[)]</code>。</p>
<p><code>(?...)</code><br />
这是一个表达式的扩展符号。<code>'?'</code>后的第一个字母决定了整个表达式的语法和含义，除了<code>(?P<name>...)</code>以外，表达式不会产生一个新的组。下面介绍几个目前已被支持的扩展：</p>
<p><code>(?iLmsux)</code><br />
<code>'i'</code>、<code>'L'</code>、<code>'m'</code>、<code>'s'</code>、<code>'u'</code>、<code>'x'</code>里的一个或多个字母。表达式不匹配任何字符，但是指定相应的标志：<strong>re.I</strong>(忽略大小写)、<strong>re.L</strong>(依赖locale)、<strong>re.M</strong>(多行模式)、<strong>re.S</strong>(.匹配所有字符)、<strong>re.U</strong>(依赖Unicode)、<strong>re.X</strong>(详细模式)。关于各个模式的区别，下面会有专门的一节来介绍的。使用这个语法可以代替在<code>re.compile()</code>的时候或者调用的时候指定<em>flag</em>参数。<br />
例如，上面举过的例子，可以改写成这样（和指定了<code>re.MULTILINE</code>是一样的效果）：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">findall</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'(?m)(foo.$)'</span>, <span style="color: #483d8b;">'foo1<span style="color: #000099; font-weight: bold;">\n</span>foo2<span style="color: #000099; font-weight: bold;">\n</span>'</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#91;</span><span style="color: #483d8b;">'foo1'</span>, <span style="color: #483d8b;">'foo2'</span><span style="color: black;">&#93;</span></pre></div></div>

<p>另外，还要注意<code>(?x)</code>标志如果有的话，要放在最前面。</p>
<p><code>(?:...)</code><br />
匹配内部的RE所匹配的内容，但是不建立<strong>组</strong>。</p>
<p><code>(?P&lt;name&gt;...)</code><br />
和普通的圆括号类似，但是子串匹配到的内容将可以用命名的<em>name</em>参数来提取。组的<em>name</em>必须是有效的python标识符，而且在本表达式内不重名。命名了的组和普通组一样，也用数字来提取，也就是说名字只是个额外的属性。<br />
演示一下：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> m=<span style="color: #dc143c;">re</span>.<span style="color: black;">match</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'(?P&lt;var&gt;[a-zA-Z_]<span style="color: #000099; font-weight: bold;">\w</span>*)'</span>, <span style="color: #483d8b;">'abc=123'</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> m.<span style="color: black;">group</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'var'</span><span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'abc'</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> m.<span style="color: black;">group</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'abc'</span></pre></div></div>

<p><code>(?P=name)</code><br />
匹配之前以<em>name</em>命名的组里的内容。<br />
演示一下：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">match</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'&lt;(?P&lt;tagname&gt;<span style="color: #000099; font-weight: bold;">\w</span>*)&gt;.*&lt;/(?P=tagname)&gt;'</span>, <span style="color: #483d8b;">'&lt;h1&gt;xxx&lt;/h2&gt;'</span><span style="color: black;">&#41;</span>  <span style="color: #808080; font-style: italic;">#这个不匹配</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">match</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'&lt;(?P&lt;tagname&gt;<span style="color: #000099; font-weight: bold;">\w</span>*)&gt;.*&lt;/(?P=tagname)&gt;'</span>, <span style="color: #483d8b;">'&lt;h1&gt;xxx&lt;/h1&gt;'</span><span style="color: black;">&#41;</span>  <span style="color: #808080; font-style: italic;">#这个匹配</span>
<span style="color: #66cc66;">&lt;</span>_sre.<span style="color: black;">SRE_Match</span> <span style="color: #008000;">object</span> at 0xb69588e0<span style="color: #66cc66;">&gt;</span></pre></div></div>

<p><code>(?#...)</code><br />
注释，圆括号里的内容会被忽略。</p>
<p><code>(?=...)</code><br />
如果 <code>...</code> 匹配接下来的字符，才算匹配，但是并不会消耗任何被匹配的字符。例如 <code>Isaac (?=Asimov)</code> 只会匹配后面跟着 <code>'Asimov'</code> 的 <code>'Isaac '</code>，这个叫做“前瞻断言”。</p>
<p><code>(?!...)</code><br />
和上面的相反，只匹配接下来的字符串<strong>不</strong>匹配 <code>...</code> 的串，这叫做“反前瞻断言”。</p>
<p><code>(?<=...)</code><br />
只有当当前位置之前的字符串匹配 <code>...</code> ，整个匹配才有效，这叫“后顾断言”。<code>(?<=abc)def</code>会找到 <code>'abcdef'</code>，因为会后向查找3个字符，看是否为abc。所以内置的子RE，需要是固定长度的，比如可以是<code>abc</code>、<code>a|b</code>，但不能是<code>a*</code>、<code>a{3,4}</code>。注意这种RE永远不会匹配到字符串的开头。举个例子，找到连字符（<code>'-'</code>）后的单词：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> m = <span style="color: #dc143c;">re</span>.<span style="color: black;">search</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'(?&lt;=-)<span style="color: #000099; font-weight: bold;">\w</span>+'</span>, <span style="color: #483d8b;">'spam-egg'</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> m.<span style="color: black;">group</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'egg'</span></pre></div></div>

<p><code>(?&lt;!...)</code><br />
同理，这个叫做“反后顾断言”，子RE需要固定长度的，含义是前面的字符串不匹配 <code>...</code> 整个才算匹配。</p>
<p><code>(?(id/name)yes-pattern|no-pattern)</code><br />
如有由<em>id</em>或者<em>name</em>指定的组存在的话，将会匹配<code>yes-pattern</code>，否则将会匹配<code>no-pattern</code>，通常情况下<code>no-pattern</code>也可以省略。例如：<code>(<)?(\w+@\w+(?:\.\w+)+)(?(1)>)</code>可以匹配 <code>'&lt;user@host.com&gt;'</code> 和 <code>'user@host.com'</code>，但是不会匹配 <code>'&lt;user@host.com'</code>。</p>
<p>下面列出以<code>'\'</code>开头的特殊序列。如果某个字符没有在下面列出，那么RE的结果会只匹配那个字母本身，比如，<code>\$</code>只匹配字面意义上的<code>'$'</code>。</p>
<p><code>\number</code><br />
匹配number所指的组相同的字符串。组的序号从1开始。例如：<code>(.+) \1</code>可以匹配<code>'the the'</code>和<code>'55 55'</code>，但不匹配<code>'the end'</code>。这种序列在一个正则表达式里最多可以有99个，如果<em>number</em>以0开头，或是有3位以上的数字，就会被当做八进制表示的字符了。同时，这个也不能用于方括号内。</p>
<p><code>\A</code><br />
只匹配字符串的开始。</p>
<p><code>\b</code><br />
匹配单词边界（包括开始和结束），这里的“单词”，是指连续的字母、数字和下划线组成的字符串。注意，<code>\b</code>的定义是<code>\w</code>和<code>\W</code>的交界，所以精确的定义有赖于<code>UNICODE</code>和<code>LOCALE</code>这两个标志位。</p>
<p><code>\B</code><br />
和<code>\b</code>相反，<code>\B</code>匹配非单词边界。也依赖于<code>UNICODE</code>和<code>LOCALE</code>这两个标志位。</p>
<p><code>\d</code><br />
未指定<code>UNICODE</code>标志时，匹配数字，等效于：<code>[0-9]</code>。指定了<code>UNICODE</code>标志时，还会匹配其他Unicode库里描述为字符串的符号。便于理解，举个例子（好不容易找的例子啊，呵呵）：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#\u2076\和u2084分别是上标的6和下标的4，属于unicode的DIGIT</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> unistr = u<span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\u</span>2076<span style="color: #000099; font-weight: bold;">\u</span>2084abc'</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span> unistr
⁶₄abc
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">findall</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\d</span>+'</span>, unistr, <span style="color: #dc143c;">re</span>.<span style="color: black;">U</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>
⁶₄</pre></div></div>

<p><code>\D</code><br />
和<code>\d</code>相反，不多说了。</p>
<p><code>\s</code><br />
当未指定<code>UNICODE</code>和<code>LOCALE</code>这两个标志位时，匹配任何空白字符，等效于<code>[ \t\n\r\f\v]</code>。如果指定了<code>LOCALE</code>，则还要加LOCALE相关的空白字符；如果指定了<code>UNICODE</code>，还要加上UNICODE空白字符，如较常见的空宽度连接空格（\uFEFF）、零宽度非连接空格(\u200B)等。</p>
<p><code>\S</code><br />
和<code>\s</code>相反，也不多说。</p>
<p><code>\w</code><br />
当未指定<code>UNICODE</code>和<code>LOCALE</code>这两个标志位时，等效于<code>[a-zA-Z0-9_]</code>。当指定了<code>LOCALE</code>时，为<code>[0-9_]</code>加上当前LOCAL指定的字母。当指定了<code>UNICODE</code>时，为<code>[0-9_]</code>加上UNICODE库里的所有字母。</p>
<p><code>\W</code><br />
和<code>\w</code>相反，不多说。</p>
<p><code>\Z</code><br />
只匹配字符串的结尾。</p>
<p><big><strong>匹配之于搜索</strong></big></p>
<p>python提供了两种基于正则表达式的操作：匹配（match）从字符串的开始检查字符串是否个正则匹配。而搜索（search）检查字符串任意位置是否有匹配的子串（perl默认就是如此）。<br />
注意，即使search的正则以<code>'^'</code>开头，match和search也还是有许多不同的。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">match</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;c&quot;</span>, <span style="color: #483d8b;">&quot;abcdef&quot;</span><span style="color: black;">&#41;</span>  <span style="color: #808080; font-style: italic;"># 不匹配</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">search</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;c&quot;</span>, <span style="color: #483d8b;">&quot;abcdef&quot;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># 匹配</span>
<span style="color: #66cc66;">&lt;</span>_sre.<span style="color: black;">SRE_Match</span> <span style="color: #008000;">object</span> at ...<span style="color: #66cc66;">&gt;</span></pre></div></div>

<p><big><strong>模块的属性和方法</strong></big></p>
<p><code>re</code>.<strong>compile</strong>(<em>pattern</em>[, <em>flags</em>])<br />
把一个正则表达式<em>pattern</em>编译成正则对象，以便可以用正则对象的<strong>match</strong>和<strong>search</strong>方法。<br />
得到的正则对象的行为（也就是模式）可以用<em>flags</em>来指定，值可以由几个下面的值OR得到。<br />
以下两段内容在语法上是等效的：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">prog = <span style="color: #dc143c;">re</span>.<span style="color: #008000;">compile</span><span style="color: black;">&#40;</span>pattern<span style="color: black;">&#41;</span>
result = prog.<span style="color: black;">match</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">string</span><span style="color: black;">&#41;</span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">result = <span style="color: #dc143c;">re</span>.<span style="color: black;">match</span><span style="color: black;">&#40;</span>pattern, <span style="color: #dc143c;">string</span><span style="color: black;">&#41;</span></pre></div></div>

<p>区别是，用了<strong>re.compile</strong>以后，正则对象会得到保留，这样在需要多次运用这个正则对象的时候，效率会有较大的提升。再用上面用过的例子来演示一下，用相同的正则匹配相同的字符串，执行100万次，就体现出compile的效率了（数据来自我那1.86G CPU的神舟本本）：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #dc143c;">timeit</span>.<span style="color: #dc143c;">timeit</span><span style="color: black;">&#40;</span>
...     <span style="color: black;">setup</span>=<span style="color: #483d8b;">''</span><span style="color: #483d8b;">'import re; reg = re.compile('</span><span style="color: #66cc66;">&lt;</span><span style="color: black;">&#40;</span><span style="color: #66cc66;">?</span>P<span style="color: #66cc66;">&lt;</span>tagname<span style="color: #66cc66;">&gt;</span>\w<span style="color: #66cc66;">*</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">&gt;</span>.<span style="color: #66cc66;">*&lt;</span>/<span style="color: black;">&#40;</span><span style="color: #66cc66;">?</span>P=tagname<span style="color: black;">&#41;</span><span style="color: #66cc66;">&gt;</span><span style="color: #483d8b;">')'</span><span style="color: #483d8b;">''</span>,
...     <span style="color: black;">stmt</span>=<span style="color: #483d8b;">''</span><span style="color: #483d8b;">'reg.match('</span><span style="color: #66cc66;">&lt;</span>h1<span style="color: #66cc66;">&gt;</span>xxx<span style="color: #66cc66;">&lt;</span>/h1<span style="color: #66cc66;">&gt;</span><span style="color: #483d8b;">')'</span><span style="color: #483d8b;">''</span>,
...     <span style="color: black;">number</span>=<span style="color: #ff4500;">1000000</span><span style="color: black;">&#41;</span>
<span style="color: #ff4500;">1.2062149047851562</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #dc143c;">timeit</span>.<span style="color: #dc143c;">timeit</span><span style="color: black;">&#40;</span>
...     <span style="color: black;">setup</span>=<span style="color: #483d8b;">''</span><span style="color: #483d8b;">'import re'</span><span style="color: #483d8b;">''</span>,
...     <span style="color: black;">stmt</span>=<span style="color: #483d8b;">''</span><span style="color: #483d8b;">'re.match('</span><span style="color: #66cc66;">&lt;</span><span style="color: black;">&#40;</span><span style="color: #66cc66;">?</span>P<span style="color: #66cc66;">&lt;</span>tagname<span style="color: #66cc66;">&gt;</span>\w<span style="color: #66cc66;">*</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">&gt;</span>.<span style="color: #66cc66;">*&lt;</span>/<span style="color: black;">&#40;</span><span style="color: #66cc66;">?</span>P=tagname<span style="color: black;">&#41;</span><span style="color: #66cc66;">&gt;</span><span style="color: #483d8b;">', '</span><span style="color: #66cc66;">&lt;</span>h1<span style="color: #66cc66;">&gt;</span>xxx<span style="color: #66cc66;">&lt;</span>/h1<span style="color: #66cc66;">&gt;</span><span style="color: #483d8b;">')'</span><span style="color: #483d8b;">''</span>,
...     <span style="color: black;">number</span>=<span style="color: #ff4500;">1000000</span><span style="color: black;">&#41;</span>
<span style="color: #ff4500;">4.4380838871002197</span></pre></div></div>

<p><code>re</code>.<strong>I</strong><br />
<code>re</code>.<strong>IGNORECASE</strong><br />
让正则表达式忽略大小写，这样一来，<code>[A-Z]</code>也可以匹配小写字母了。此特性和locale无关。</p>
<p><code>re</code>.<strong>L</strong><br />
<code>re</code>.<strong>LOCALE</strong><br />
让<code>\w</code>、<code>\W</code>、<code>\b</code>、<code>\B</code>、<code>\s</code>和<code>\S</code>依赖当前的locale。</p>
<p><code>re</code>.<strong>M</strong><br />
<code>re</code>.<strong>MULTILINE</strong><br />
影响<code>'^'</code>和<code>'$'</code>的行为，指定了以后，<code>'^'</code>会增加匹配每行的开始（也就是换行符后的位置）；<code>'$'</code>会增加匹配每行的结束（也就是换行符前的位置）。</p>
<p><code>re</code>.<strong>S</strong><br />
<code>re</code>.<strong>DOTALL</strong><br />
影响<code>'.'</code>的行为，平时<code>'.'</code>匹配除换行符以外的所有字符，指定了本标志以后，也可以匹配换行符。</p>
<p><code>re</code>.<strong>U</strong><br />
<code>re</code>.<strong>UNICODE</strong><br />
让<code>\w</code>、<code>\W</code>、<code>\b</code>、<code>\B</code>、<code>\d</code>、<code>\D</code>、<code>\s</code>和<code>\S</code>依赖Unicode库。</p>
<p><code>re</code>.<strong>X</strong><br />
<code>re</code>.<strong>VERBOSE</strong><br />
运用这个标志，你可以写出可读性更好的正则表达式：除了在方括号内的和被反斜杠转义的以外的所有空白字符，都将被忽略，而且每行中，一个正常的井号后的所有字符也被忽略，这样就可以方便地在正则表达式内部写注释了。也就是说，下面两个正则表达式是等效的：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">a = <span style="color: #dc143c;">re</span>.<span style="color: #008000;">compile</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">&quot;&quot;&quot;<span style="color: #000099; font-weight: bold;">\d</span> +  # the integral part
                   <span style="color: #000099; font-weight: bold;">\.</span>    # the decimal point
                   <span style="color: #000099; font-weight: bold;">\d</span> *  # some fractional digits&quot;&quot;&quot;</span>, <span style="color: #dc143c;">re</span>.<span style="color: black;">X</span><span style="color: black;">&#41;</span>
b = <span style="color: #dc143c;">re</span>.<span style="color: #008000;">compile</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\d</span>+<span style="color: #000099; font-weight: bold;">\.</span><span style="color: #000099; font-weight: bold;">\d</span>*&quot;</span><span style="color: black;">&#41;</span></pre></div></div>

<p><code>re</code>.<strong>search</strong>(<em>pattern</em>, <em>string</em>[, <em>flags</em>])<br />
扫描<em>string</em>，看是否有个位置可以匹配正则表达式<em>pattern</em>。如果找到了，就返回一个<strong>MatchObject</strong>的实例，否则返回<strong>None</strong>，注意这和找到长度为0的子串含义是不一样的。搜索过程受<em>flags</em>的影响。</p>
<p><code>re</code>.<strong>match</strong>(<em>pattern</em>, <em>string</em>[, <em>flags</em>])<br />
如果字符串<em>string</em>的开头和正则表达式<em>pattern</em>匹配的话，返回一个相应的<strong>MatchObject</strong>的实例，否则返回<strong>None</strong></p>
<blockquote><p>注意：要在字符串的任意位置搜索的话，需要使用上面的<strong>search()</strong>。</p></blockquote>
<p><code>re</code>.<strong>split</strong>(<em>pattern</em>, <em>string</em>[, <em>maxsplit=0</em>])<br />
用匹配<em>pattern</em>的子串来分割<em>string</em>，如果<em>pattern</em>里使用了圆括号，那么被<em>pattern</em>匹配到的串也将作为返回值列表的一部分。如果<em>maxsplit</em>不为0，则最多被分割为<em>maxsplit</em>个子串，剩余部分将整个地被返回。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\W</span>+'</span>, <span style="color: #483d8b;">'Words, words, words.'</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#91;</span><span style="color: #483d8b;">'Words'</span>, <span style="color: #483d8b;">'words'</span>, <span style="color: #483d8b;">'words'</span>, <span style="color: #483d8b;">''</span><span style="color: black;">&#93;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'(<span style="color: #000099; font-weight: bold;">\W</span>+)'</span>, <span style="color: #483d8b;">'Words, words, words.'</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#91;</span><span style="color: #483d8b;">'Words'</span>, <span style="color: #483d8b;">', '</span>, <span style="color: #483d8b;">'words'</span>, <span style="color: #483d8b;">', '</span>, <span style="color: #483d8b;">'words'</span>, <span style="color: #483d8b;">'.'</span>, <span style="color: #483d8b;">''</span><span style="color: black;">&#93;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\W</span>+'</span>, <span style="color: #483d8b;">'Words, words, words.'</span>, <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#91;</span><span style="color: #483d8b;">'Words'</span>, <span style="color: #483d8b;">'words, words.'</span><span style="color: black;">&#93;</span></pre></div></div>

<p>如果正则有圆括号，并且可以匹配到字符串的开始位置的时候，返回值的第一项，会多出一个空字符串。匹配到字符结尾也是同样的道理：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'(<span style="color: #000099; font-weight: bold;">\W</span>+)'</span>, <span style="color: #483d8b;">'...words, words...'</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#91;</span><span style="color: #483d8b;">''</span>, <span style="color: #483d8b;">'...'</span>, <span style="color: #483d8b;">'words'</span>, <span style="color: #483d8b;">', '</span>, <span style="color: #483d8b;">'words'</span>, <span style="color: #483d8b;">'...'</span>, <span style="color: #483d8b;">''</span><span style="color: black;">&#93;</span></pre></div></div>

<p>注意，<em>split</em>不会被零长度的正则所分割，例如：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'x*'</span>, <span style="color: #483d8b;">'foo'</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#91;</span><span style="color: #483d8b;">'foo'</span><span style="color: black;">&#93;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;(?m)^$&quot;</span>, <span style="color: #483d8b;">&quot;foo<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>bar<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#91;</span><span style="color: #483d8b;">'foo<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>bar<span style="color: #000099; font-weight: bold;">\n</span>'</span><span style="color: black;">&#93;</span></pre></div></div>

<p><code>re</code>.<strong>findall</strong>(<em>pattern</em>, <em>string</em>[, <em>flags</em>])<br />
以列表的形式返回<em>string</em>里匹配<em>pattern</em>的不重叠的子串。<em>string</em>会被从左到右依次扫描，返回的列表也是从左到右一次匹配到的。如果<em>pattern</em>里含有<strong>组</strong>的话，那么会返回匹配到的组的列表；如果<em>pattern</em>里有多个组，那么各组会先组成一个元组，然后返回值将是一个元组的列表。<br />
由于这个函数不会涉及到<strong>MatchObject</strong>之类的概念，所以，对新手来说，应该是最好理解也最容易使用的一个函数了。下面就此来举几个简单的例子：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#简单的findall</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">findall</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\w</span>+'</span>, <span style="color: #483d8b;">'hello, world!'</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#91;</span><span style="color: #483d8b;">'hello'</span>, <span style="color: #483d8b;">'world'</span><span style="color: black;">&#93;</span>
<span style="color: #808080; font-style: italic;">#这个返回的就是元组的列表</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">findall</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'(<span style="color: #000099; font-weight: bold;">\d</span>+)<span style="color: #000099; font-weight: bold;">\.</span>(<span style="color: #000099; font-weight: bold;">\d</span>+)<span style="color: #000099; font-weight: bold;">\.</span>(<span style="color: #000099; font-weight: bold;">\d</span>+)<span style="color: #000099; font-weight: bold;">\.</span>(<span style="color: #000099; font-weight: bold;">\d</span>+)'</span>, <span style="color: #483d8b;">'My IP is 192.168.0.2, and your is 192.168.0.3.'</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#91;</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'192'</span>, <span style="color: #483d8b;">'168'</span>, <span style="color: #483d8b;">'0'</span>, <span style="color: #483d8b;">'2'</span><span style="color: black;">&#41;</span>, <span style="color: black;">&#40;</span><span style="color: #483d8b;">'192'</span>, <span style="color: #483d8b;">'168'</span>, <span style="color: #483d8b;">'0'</span>, <span style="color: #483d8b;">'3'</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span></pre></div></div>

<p><code>re</code>.<strong> finditer</strong>(<em>pattern</em>, <em>string</em>[, <em>flags</em>])<br />
和上面的<strong>findall()</strong>类似，但返回的是<strong>MatchObject</strong>的实例的迭代器。<br />
还是例子说明问题：<br />
>>> for m in re.finditer('\w+', 'hello, world!'):<br />
...     print m.group()<br />
...<br />
hello<br />
world
</pre>
<p><code>re</code>.<strong>sub</strong>(<em>pattern</em>, <em>repl</em>, <em>string</em>[, <em>count</em>])<br />
替换，将<em>string</em>里，匹配<em>pattern</em>的部分，用<em>repl</em>替换掉，最多替换<em>count</em>次（剩余的匹配将不做处理），然后返回替换后的字符串。如果<em>string</em>里没有可以匹配<em>pattern</em>的串，将被原封不动地返回。<em>repl</em>可以是一个字符串，也可以是一个函数（也可以参考我以前的<a href="http://luy.li/2009/04/01/python_re/">例子</a>）。如果<em>repl</em>是个字符串，则其中的反斜杆会被处理过，比如 <code>\n</code> 会被转成换行符，反斜杆加数字会被替换成相应的组，比如 <code>\6</code> 表示<em>pattern</em>匹配到的第6个组的内容。<br />
例子：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">sub</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'def<span style="color: #000099; font-weight: bold;">\s</span>+([a-zA-Z_][a-zA-Z_0-9]*)<span style="color: #000099; font-weight: bold;">\s</span>*<span style="color: #000099; font-weight: bold;">\(</span><span style="color: #000099; font-weight: bold;">\s</span>*<span style="color: #000099; font-weight: bold;">\)</span>:'</span>,
...        <span style="color: black;">r</span><span style="color: #483d8b;">'static PyObject*<span style="color: #000099; font-weight: bold;">\n</span>py_<span style="color: #000099; font-weight: bold;">\1</span>(void)<span style="color: #000099; font-weight: bold;">\n</span>{'</span>,
...        <span style="color: #483d8b;">'def myfunc():'</span><span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'static PyObject*<span style="color: #000099; font-weight: bold;">\n</span>py_myfunc(void)<span style="color: #000099; font-weight: bold;">\n</span>{'</span></pre></div></div>

<p>如果<em>repl</em>是个函数，每次<em>pattern</em>被匹配到的时候，都会被调用一次，传入一个匹配到的<strong>MatchObject</strong>对象，需要返回一个字符串，在匹配到的位置，就填入返回的字符串。<br />
例子：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">def</span> dashrepl<span style="color: black;">&#40;</span>matchobj<span style="color: black;">&#41;</span>:
...     <span style="color: #ff7700;font-weight:bold;">if</span> matchobj.<span style="color: black;">group</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span> == <span style="color: #483d8b;">'-'</span>: <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">' '</span>
...     <span style="color: #ff7700;font-weight:bold;">else</span>: <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">'-'</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">sub</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'-{1,2}'</span>, dashrepl, <span style="color: #483d8b;">'pro----gram-files'</span><span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'pro--gram files'</span></pre></div></div>

<p>零长度的匹配也会被替换，比如：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">sub</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'x*'</span>, <span style="color: #483d8b;">'-'</span>, <span style="color: #483d8b;">'abcxxd'</span><span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'-a-b-c-d-'</span></pre></div></div>

<p>特殊地，在替换字符串里，如果有<code>\g<name></code>这样的写法，将匹配正则的命名组（前面介绍过的，<code>(?P<name>...)</code>这样定义出来的东西）。<code>\g<number></code>这样的写法，也是数字的组，也就是说，<code>\g<2></code>一般和<code>\2</code>是等效的，但是万一你要在<code>\2</code>后面紧接着写上字面意义的0，你就不能写成<code>\20</code>了（因为这代表第20个组），这时候必须写成<code>\g<2>0</code>，另外，<code>\g<0></code>代表匹配到的整个子串。<br />
例子：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">sub</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'-(<span style="color: #000099; font-weight: bold;">\d</span>+)-'</span>, <span style="color: #483d8b;">'-<span style="color: #000099; font-weight: bold;">\g</span>&lt;1&gt;0<span style="color: #000099; font-weight: bold;">\g</span>&lt;0&gt;'</span>, <span style="color: #483d8b;">'a-11-b-22-c'</span><span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'a-110-11-b-220-22-c'</span></pre></div></div>

<p><code>re</code>.<strong>subn</strong>(<em>pattern</em>, <em>repl</em>, <em>string</em>[, <em>count</em>])<br />
跟上面的<code>sub()</code>函数一样，只是它返回的是一个元组 <code>(新字符串, 匹配到的次数)</code><br />
，还是用例子说话：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">subn</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'-(<span style="color: #000099; font-weight: bold;">\d</span>+)-'</span>, <span style="color: #483d8b;">'-<span style="color: #000099; font-weight: bold;">\g</span>&lt;1&gt;0<span style="color: #000099; font-weight: bold;">\g</span>&lt;0&gt;'</span>, <span style="color: #483d8b;">'a-11-b-22-c'</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#40;</span><span style="color: #483d8b;">'a-110-11-b-220-22-c'</span>, <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span></pre></div></div>

<p><code>re</code>.<strong>escape</strong>(<em>string</em>)<br />
把<em>string</em>中，除了字母和数字以外的字符，都加上反斜杆。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">escape</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'abc123_@#$'</span><span style="color: black;">&#41;</span>
abc123\_\@\<span style="color: #808080; font-style: italic;">#\$</span></pre></div></div>

<p><em>exception</em> <code>re</code>.<strong>error</strong><br />
如果字符串不能被成功编译成正则表达式或者正则表达式在匹配过程中出错了，都会抛出此异常。但是如果正则表达式没有匹配到任何文本，是不会抛出这个异常的。</p>
<p><big><strong>正则对象</strong></big></p>
<p>正则对象由<code>re</code>.<strong>compile()</strong>返回。它有如下的属性和方法。</p>
<p><strong>match</strong>(<em>string</em>[, <em>pos</em>[, <em>endpos</em>]])<br />
作用和模块的<strong>match()</strong>函数类似，区别就是后面两个参数。<br />
<em>pos</em>是开始搜索的位置，默认为0。<em>endpos</em>是搜索的结束位置，如果<em>endpos</em>比<em>pos</em>还小的话，结果肯定是空的。也就是说只有<em>pos</em> 到 <em>endpos</em>-1 位置的字符串将会被搜索。<br />
例子：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> pattern = <span style="color: #dc143c;">re</span>.<span style="color: #008000;">compile</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;o&quot;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> pattern.<span style="color: black;">match</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;dog&quot;</span><span style="color: black;">&#41;</span>      <span style="color: #808080; font-style: italic;"># 开始位置不是o，所以不匹配</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> pattern.<span style="color: black;">match</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;dog&quot;</span>, <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>   <span style="color: #808080; font-style: italic;"># 第二个字符是o，所以匹配</span>
<span style="color: #66cc66;">&lt;</span>_sre.<span style="color: black;">SRE_Match</span> <span style="color: #008000;">object</span> at ...<span style="color: #66cc66;">&gt;</span></pre></div></div>

<p><strong>search</strong>(<em>string</em>[, <em>pos</em>[, <em>endpos</em>]])<br />
作用和模块的<strong>search()</strong>函数类似，<em>pos</em>和<em>endpos</em>参数和上面的<strong>match()</strong>函数类似。</p>
<p><strong>split</strong>(<em>string</em>[, <em>maxsplit</em>=0])<br />
<strong>findall</strong>(<em>string</em>[, <em>pos</em>[, <em>endpos</em>]])<br />
<strong>finditer</strong>(<em>string</em>[, <em>pos</em>[, <em>endpos</em>]])<br />
<strong>sub</strong>(<em>repl</em>, <em>string</em>[, <em>count=0</em>])<br />
<strong>subn</strong>(<em>repl</em>, <em>string</em>[, <em>count=0</em>])<br />
这几个函数，都和模块的相应函数一致。</p>
<p><strong>flags</strong><br />
编译本RE时，指定的标志位，如果未指定任何标志位，则为0。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> pattern = <span style="color: #dc143c;">re</span>.<span style="color: #008000;">compile</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;o&quot;</span>, <span style="color: #dc143c;">re</span>.<span style="color: black;">S</span>|re.<span style="color: black;">U</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> pattern.<span style="color: black;">flags</span>
<span style="color: #ff4500;">48</span></pre></div></div>

<p><strong>groups</strong><br />
RE所含有的组的个数。</p>
<p><strong>groupindex</strong><br />
一个字典，定义了命名组的名字和序号之间的关系。<br />
例子：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">这个正则有<span style="color: #ff4500;">3</span>个组，如果匹配到，第一个叫区号，最后一个叫分机号，中间的那个未命名
<span style="color: #66cc66;">&gt;&gt;&gt;</span> pattern = <span style="color: #dc143c;">re</span>.<span style="color: #008000;">compile</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;(?P&lt;quhao&gt;<span style="color: #000099; font-weight: bold;">\d</span>+)-(<span style="color: #000099; font-weight: bold;">\d</span>+)-(?P&lt;fenjihao&gt;<span style="color: #000099; font-weight: bold;">\d</span>+)&quot;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> pattern.<span style="color: black;">groups</span>
<span style="color: #ff4500;">3</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> pattern.<span style="color: black;">groupindex</span>
<span style="color: black;">&#123;</span><span style="color: #483d8b;">'fenjihao'</span>: <span style="color: #ff4500;">3</span>, <span style="color: #483d8b;">'quhao'</span>: <span style="color: #ff4500;">1</span><span style="color: black;">&#125;</span></pre></div></div>

<p><strong>pattern</strong><br />
建立本RE的原始字符串，相当于源代码了，呵呵。<br />
还是上面这个正则，可以看到，会原样返回：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span> pattern.<span style="color: black;">pattern</span>
<span style="color: black;">&#40;</span><span style="color: #66cc66;">?</span>P<span style="color: #66cc66;">&lt;</span>quhao<span style="color: #66cc66;">&gt;</span>\d+<span style="color: black;">&#41;</span>-<span style="color: black;">&#40;</span>\d+<span style="color: black;">&#41;</span>-<span style="color: black;">&#40;</span><span style="color: #66cc66;">?</span>P<span style="color: #66cc66;">&lt;</span>fenjihao<span style="color: #66cc66;">&gt;</span>\d+<span style="color: black;">&#41;</span></pre></div></div>

<p><big><strong>Match对象</strong></big></p>
<p><code>re</code>.<strong>MatchObject</strong>被用于布尔判断的时候，始终返回True，所以你用 if 语句来判断某个 <strong>match()</strong> 是否成功是安全的。<br />
它有以下方法和属性：</p>
<p><strong>expand</strong>(<em>template</em>)<br />
用<em>template</em>做为模板，将<strong>MatchObject</strong>展开，就像<strong>sub()</strong>里的行为一样，看例子：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> m = <span style="color: #dc143c;">re</span>.<span style="color: black;">match</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'a=(<span style="color: #000099; font-weight: bold;">\d</span>+)'</span>, <span style="color: #483d8b;">'a=100'</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> m.<span style="color: black;">expand</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'above a is <span style="color: #000099; font-weight: bold;">\g</span>&lt;1&gt;'</span><span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'above a is 100'</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> m.<span style="color: black;">expand</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'above a is <span style="color: #000099; font-weight: bold;">\1</span>'</span><span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'above a is 100'</span></pre></div></div>

<p><strong>group</strong>([<em>group1</em>, <em>...</em>])<br />
返回一个或多个子组。如果参数为一个，就返回一个子串；如果参数有多个，就返回多个子串注册的元组。如果不传任何参数，效果和传入一个0一样，将返回整个匹配。如果某个<em>groupN</em>未匹配到，相应位置会返回<strong>None</strong>。如果某个<em>groupN</em>是负数或者大于group的总数，则会抛出<strong>IndexError</strong>异常。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> m = <span style="color: #dc143c;">re</span>.<span style="color: black;">match</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">&quot;(<span style="color: #000099; font-weight: bold;">\w</span>+) (<span style="color: #000099; font-weight: bold;">\w</span>+)&quot;</span>, <span style="color: #483d8b;">&quot;Isaac Newton, physicist&quot;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> m.<span style="color: black;">group</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>       <span style="color: #808080; font-style: italic;"># 整个匹配</span>
<span style="color: #483d8b;">'Isaac Newton'</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> m.<span style="color: black;">group</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>       <span style="color: #808080; font-style: italic;"># 第一个子串</span>
<span style="color: #483d8b;">'Isaac'</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> m.<span style="color: black;">group</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span>       <span style="color: #808080; font-style: italic;"># 第二个子串</span>
<span style="color: #483d8b;">'Newton'</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> m.<span style="color: black;">group</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span>    <span style="color: #808080; font-style: italic;"># 多个子串组成的元组</span>
<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Isaac'</span>, <span style="color: #483d8b;">'Newton'</span><span style="color: black;">&#41;</span></pre></div></div>

<p>如果有其中有用<code>(?P<name>...)</code>这种语法命名过的子串的话，相应的<em>groupN</em>也可以是名字字符串。例如：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> m = <span style="color: #dc143c;">re</span>.<span style="color: black;">match</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">&quot;(?P&lt;first_name&gt;<span style="color: #000099; font-weight: bold;">\w</span>+) (?P&lt;last_name&gt;<span style="color: #000099; font-weight: bold;">\w</span>+)&quot;</span>, <span style="color: #483d8b;">&quot;Malcolm Reynolds&quot;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> m.<span style="color: black;">group</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'first_name'</span><span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'Malcolm'</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> m.<span style="color: black;">group</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'last_name'</span><span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'Reynolds'</span></pre></div></div>

<p>如果某个组被匹配到多次，那么只有最后一次的数据，可以被提取到：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> m = <span style="color: #dc143c;">re</span>.<span style="color: black;">match</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">&quot;(..)+&quot;</span>, <span style="color: #483d8b;">&quot;a1b2c3&quot;</span><span style="color: black;">&#41;</span>  <span style="color: #808080; font-style: italic;"># 匹配到3次</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> m.<span style="color: black;">group</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>                        <span style="color: #808080; font-style: italic;"># 返回的是最后一次</span>
<span style="color: #483d8b;">'c3'</span></pre></div></div>

<p><strong>groups</strong>([<em>default</em>])<br />
返回一个由所有匹配到的子串组成的元组。<em>default</em>参数，用于给那些没有匹配到的组做默认值，它的默认值是<strong>None</strong><br />
例如：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> m = <span style="color: #dc143c;">re</span>.<span style="color: black;">match</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">&quot;(<span style="color: #000099; font-weight: bold;">\d</span>+)<span style="color: #000099; font-weight: bold;">\.</span>(<span style="color: #000099; font-weight: bold;">\d</span>+)&quot;</span>, <span style="color: #483d8b;">&quot;24.1632&quot;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> m.<span style="color: black;">groups</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#40;</span><span style="color: #483d8b;">'24'</span>, <span style="color: #483d8b;">'1632'</span><span style="color: black;">&#41;</span></pre></div></div>

<p><em>default</em>的作用：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> m = <span style="color: #dc143c;">re</span>.<span style="color: black;">match</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">&quot;(<span style="color: #000099; font-weight: bold;">\d</span>+)<span style="color: #000099; font-weight: bold;">\.</span>?(<span style="color: #000099; font-weight: bold;">\d</span>+)?&quot;</span>, <span style="color: #483d8b;">&quot;24&quot;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> m.<span style="color: black;">groups</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>      <span style="color: #808080; font-style: italic;"># 第二个默认是None</span>
<span style="color: black;">&#40;</span><span style="color: #483d8b;">'24'</span>, <span style="color: #008000;">None</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> m.<span style="color: black;">groups</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'0'</span><span style="color: black;">&#41;</span>   <span style="color: #808080; font-style: italic;"># 现在默认是0了</span>
<span style="color: black;">&#40;</span><span style="color: #483d8b;">'24'</span>, <span style="color: #483d8b;">'0'</span><span style="color: black;">&#41;</span></pre></div></div>

<p><strong>groupdict</strong>([<em>default</em>])<br />
返回一个包含所有命名组的名字和子串的字典，<em>default</em>参数，用于给那些没有匹配到的组做默认值，它的默认值是<strong>None</strong>，例如：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> m = <span style="color: #dc143c;">re</span>.<span style="color: black;">match</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">&quot;(?P&lt;first_name&gt;<span style="color: #000099; font-weight: bold;">\w</span>+) (?P&lt;last_name&gt;<span style="color: #000099; font-weight: bold;">\w</span>+)&quot;</span>, <span style="color: #483d8b;">&quot;Malcolm Reynolds&quot;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> m.<span style="color: black;">groupdict</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#123;</span><span style="color: #483d8b;">'first_name'</span>: <span style="color: #483d8b;">'Malcolm'</span>, <span style="color: #483d8b;">'last_name'</span>: <span style="color: #483d8b;">'Reynolds'</span><span style="color: black;">&#125;</span></pre></div></div>

<p><strong>start</strong>([<strong>group</strong>])<br />
<strong>end</strong>([<em>group</em>])<br />
返回的是：被组<em>group</em>匹配到的子串在原字符串中的位置。如果不指定<em>group</em>或<em>group</em>指定为0，则代表整个匹配。如果<em>group</em>未匹配到，则返回 <code>-1</code>。<br />
对于指定的m和g，<code>m.group(g)</code>和<code>m.string[m.start(g):m.end(g)]</code>等效。<br />
注意：如果<em>group</em>匹配到空字符串，<em>m.start(group)</em>和<em>m.end(group)</em>将相等。<br />
例如：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> m = <span style="color: #dc143c;">re</span>.<span style="color: black;">search</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'b(c?)'</span>, <span style="color: #483d8b;">'cba'</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> m.<span style="color: black;">start</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
<span style="color: #ff4500;">1</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> m.<span style="color: black;">end</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
<span style="color: #ff4500;">2</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> m.<span style="color: black;">start</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
<span style="color: #ff4500;">2</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> m.<span style="color: black;">end</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
<span style="color: #ff4500;">2</span></pre></div></div>

<p>下面是一个把email地址里的“remove_this”去掉的例子：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #dc143c;">email</span> = <span style="color: #483d8b;">&quot;tony@tiremove_thisger.net&quot;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> m = <span style="color: #dc143c;">re</span>.<span style="color: black;">search</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;remove_this&quot;</span>, <span style="color: #dc143c;">email</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #dc143c;">email</span><span style="color: black;">&#91;</span>:m.<span style="color: black;">start</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span> + <span style="color: #dc143c;">email</span><span style="color: black;">&#91;</span>m.<span style="color: black;">end</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:<span style="color: black;">&#93;</span>
<span style="color: #483d8b;">'tony@tiger.net'</span></pre></div></div>

<p><strong>span</strong>([<em>group</em>])<br />
返回一个元组： <code>(m.start(group), m.end(group))</code></p>
<p><strong>pos</strong><br />
就是传给RE对象的<strong>search()</strong>或<strong>match()</strong>方法的参数<em>pos</em>，代表RE开始搜索字符串的位置。</p>
<p><strong>endpos</strong><br />
就是传给RE对象的<strong>search()</strong>或<strong>match()</strong>方法的参数<em>endpos</em>，代表RE搜索字符串的结束位置。</p>
<p><strong>lastindex</strong><br />
最后一次匹配到的组的数字序号，如果没有匹配到，将得到<strong>None</strong>。<br />
例如：<code>(a)b</code>、<code>((a)(b))</code>和<code>((ab))</code>正则去匹配<code>'ab'</code>的话，得到的<strong>lastindex</strong>为1。而用<code>(a)(b)</code>去匹配<code>'ab'</code>的话，得到的<strong>lastindex</strong>为2。</p>
<p><strong>lastgroup</strong><br />
最后一次匹配到的组的名字，如果没有匹配到或者最后的组没有名字，将得到<strong>None</strong>。</p>
<p><strong>re</strong><br />
得到本Match对象的正则表达式对象，也就是执行<strong>search()</strong>或<strong>match()</strong>的对象。</p>
<p><strong>string</strong><br />
传给<strong>search()</strong>或<strong>match()</strong>的字符串。</p>
<p><br/></p>
<p>后面的例子就略了吧，文中已经加了很多我自己的例子了，需要更多例子的话，参照英文原文吧。<br />
最后，感谢我的老婆辛苦地帮我校对，哈哈。</p>
]]></content:encoded>
			<wfw:commentRss>http://luy.li/2010/05/12/python-re/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>python程序，在windows下调用子进程，不产生cmd窗口的办法</title>
		<link>http://luy.li/2010/04/24/python_windows_no_cmd/</link>
		<comments>http://luy.li/2010/04/24/python_windows_no_cmd/#comments</comments>
		<pubDate>Sat, 24 Apr 2010 12:16:47 +0000</pubDate>
		<dc:creator>bones7456</dc:creator>
				<category><![CDATA[编程相关]]></category>

		<guid isPermaLink="false">http://li2z.cn/?p=1479</guid>
		<description><![CDATA[python写的GTK程序，会有这样一个怪现象，本来在cmd下用 python xxx.py 启动，还好好的，但是用py2exe编译以后，再用subprocess调用命令行程序的时候，就发现一个黑乎乎的cmd窗口跳出来了，特别难看，要消除它其实也还比较容易，但是要使用startupinfo这个windows only的参数，以下代码是linux和windows通用的例子： if os.name == 'nt': startupinfo = subprocess.STARTUPINFO&#40;&#41; startupinfo.dwFlags &#124;= subprocess.STARTF_USESHOWWINDOW startupinfo.wShowWindow = subprocess.SW_HIDE else: startupinfo = None subprocess.Popen&#40;要运行的命令, startupinfo=startupinfo&#41; 经过今天的修改，gmbox 0.2.4 beta 已经基本能在win下运行了，哈哈。 PS：贴一个ultraedit的python语法高亮文件，偶尔在win下改改代码可能会用到，在这里。]]></description>
			<content:encoded><![CDATA[<p>python写的GTK程序，会有这样一个怪现象，本来在cmd下用 python xxx.py 启动，还好好的，但是用<a href="http://luy.li/2009/06/20/py2exe/">py2exe编译</a>以后，再用<a href="http://luy.li/2010/04/14/python_subprocess/">subprocess</a>调用命令行程序的时候，就发现一个黑乎乎的cmd窗口跳出来了，特别难看，要消除它其实也还比较容易，但是要使用startupinfo这个windows only的参数，以下代码是linux和windows通用的例子：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">name</span> == <span style="color: #483d8b;">'nt'</span>:
    startupinfo = <span style="color: #dc143c;">subprocess</span>.<span style="color: black;">STARTUPINFO</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    startupinfo.<span style="color: black;">dwFlags</span> |= <span style="color: #dc143c;">subprocess</span>.<span style="color: black;">STARTF_USESHOWWINDOW</span>
    startupinfo.<span style="color: black;">wShowWindow</span> = <span style="color: #dc143c;">subprocess</span>.<span style="color: black;">SW_HIDE</span>
<span style="color: #ff7700;font-weight:bold;">else</span>:
    startupinfo = <span style="color: #008000;">None</span>
<span style="color: #dc143c;">subprocess</span>.<span style="color: black;">Popen</span><span style="color: black;">&#40;</span>要运行的命令, startupinfo=startupinfo<span style="color: black;">&#41;</span></pre></div></div>

<p>经过今天的修改，gmbox 0.2.4 beta 已经基本能在win下运行了，哈哈。</p>
<p>PS：贴一个ultraedit的python语法高亮文件，偶尔在win下改改代码可能会用到，在<a href="http://www.ultraedit.com/forums/download/file.php?id=184&#038;sid=ed28286fa6063f3f0c9dbee486a361e3">这里</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://luy.li/2010/04/24/python_windows_no_cmd/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
