python

11月 242010
 
python os模块提供多种实现方法
[root@dm 桌面]# python
Python 2.6.5 (r265:79063, Jul 14 2010, 11:36:23)
[GCC 4.4.4 20100630 (Red Hat 4.4.4-10)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> return_status = os.system('ping -c 5 localhost')
PING localhost.localdomain (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost.localdomain (127.0.0.1): icmp_seq=1 ttl=64 time=0.022 ms
64 bytes from localhost.localdomain (127.0.0.1): icmp_seq=2 ttl=64 time=0.013 ms
64 bytes from localhost.localdomain (127.0.0.1): icmp_seq=3 ttl=64 time=0.016 ms
64 bytes from localhost.localdomain (127.0.0.1): icmp_seq=4 ttl=64 time=0.016 ms
64 bytes from localhost.localdomain (127.0.0.1): icmp_seq=5 ttl=64 time=0.024 ms

--- localhost.localdomain ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 3999ms
rtt min/avg/max/mdev = 0.013/0.018/0.024/0.005 ms
>>> import os
>>> output = os.popen('ping -c 5 localhost')
>>> print output.read()
PING localhost.localdomain (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost.localdomain (127.0.0.1): icmp_seq=1 ttl=64 time=0.024 ms
64 bytes from localhost.localdomain (127.0.0.1): icmp_seq=2 ttl=64 time=0.016 ms
64 bytes from localhost.localdomain (127.0.0.1): icmp_seq=3 ttl=64 time=0.014 ms
64 bytes from localhost.localdomain (127.0.0.1): icmp_seq=4 ttl=64 time=0.008 ms
64 bytes from localhost.localdomain (127.0.0.1): icmp_seq=5 ttl=64 time=0.011 ms

--- localhost.localdomain ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 3999ms
rtt min/avg/max/mdev = 0.008/0.014/0.024/0.006 ms
>>> import os
>>> stdin, stdout = os.popen2('sed s/p/q/g')
__main__:1: DeprecationWarning: os.popen2 is deprecated.  Use the subprocess module.
>>> stdin.writelines('Replace the ps with qs please')
>>> stdin.close()
>>> print stdout.readline()
Reqlace the qs with qs qlease
判断文件是否可读可执行
#!/usr/bin/env python
import os
filename = 'bin/gawk'
if not os.path.exists(filename):
    print filename, 'does not exists!'
    raise SystemExit, 2

if not os.access(filename, os.R_OK):
    print filename, 'is not readable!'
    raise SystemExit, 3

if not os.access(filename, os.X_OK):
    print filename, 'is not executable!'
    raise SystemExit, 4
查看文件创建时间,修改时间
import datetime
import os
filename = 'somedir/somefile'
ctime = datetime.datetime.fromtimestamp(os.path.getctime(filename))
mtime = datetime.datetime.fromtimestamp(os.path.getmtime(filename))
atime = datetime.datetime.fromtimestamp(os.path.getatime(filename))
sizeinbytes = os.path.getsize(filename)
访问环境变量
import os
homedir = os.environ['HOME']
if not '/opt/mysuite/bin' in os.environ['PATH']:
    os.environ['PATH'] += ':/opt/mysuite/bin'
os.system('mysuiteapp')
创建文件夹和链接
import os
os.mkdir('newdir')
os.makedirs('notexistent/bogus/newdir')
import os
os.link('file', 'newhardlink') # 硬链接
os.symlink('fileordir', 'newsymlink') # 符号链接
删除文件和文件夹
import os
os.remove('unneeded/file')
import os
os.rmdir('some/empty/dir')
os.removedirs('other/empty/dir')
import shutil
shutil.rmtree('any/dir/empty/or/not')
更改文件和文件夹名
import os
os.rename('somefile', 'somewhere/else')
import os
os.renames('somefile', 'even/some/dirs/that/dont/exist')
import shutil
shutil.move('somefile', 'somewhere/else')
复制文件和文件夹
import shutil # This is the module that will replace most shell operations
shutil.copy('/path/to/somefile', 'path/to/the/copy') # works just like cp
shutil.copy2('somefile', '/path/to/copy') # works just like cp -p
import shutil
shutil.copytree('src/directory', 'dst/directory') # This copies the tree and the targets of symlinks
shutil.copytree('src/directory', 'dst/directory', symlinks=True) # This copies the tree and the symlinks themselves
 Posted by at 12:42 下午
11月 152010
 


matplotlib
Matplotlib 是一个在python下实现的类matlab 的纯python 的三方库,旨在用python
实现matlab 的功能,是python下最出色的绘图库,功能很完善,其风格跟matlab很相似。先安装numpy 库(一个python 下数组处理的三方库,可以很方便的处理矩阵,数组),对于做数据图,其原理很简单,就是把函数变成关于X,Y,Z 的坐标点的数组。


标准安装的Python中用列表(list)保存一组值,可以用来当作数组使用,不过由于列表的元素可以是任
何对象,因此列表中所保存的是对象的指针。这样为了保存一个简单的[1,2,3],需要有3个指针和三个
整数对象。对于数值运算来说这种结构显然比较浪费内存和CPU计算时间。
此外Python还提供了一个array模块,array对象和列表不同,它直接保存数值,和C语言的一维数组比
较类似。但是由于它不支持多维,也没有各种运算函数,因此也不适合做数值运算。
NumPy的诞生弥补了这些不足,NumPy提供了两种基本的对象:ndarray(N-dimensional array
object)和ufunc(universal function object)。ndarray(下文统一称之为数组)是存储单一数据类
型的多维数组,而ufunc则是能够对数组进行处理的函数。
NumPy为Python带来了真正的多维数组功能,并且提供了丰富的函数库处理这些数组。它将常用的
数学函数都进行数组化,使得这些数学函数能够直接对数组进行操作,将本来需要在Python级别进行
的循环,放到C语言的运算中,明显地提高了程序的运算速度。
1.ndarray对象
导入函数库
import numpy as np
创建
通过给array函数传递Python的序列对象创建数组,如果传递的是多层嵌套的序列,将创建多
维数组
>>> a = np.array([1, 2, 3, 4])
>>> b = np.array((5, 6, 7, 8))
>>> c = np.array([[1, 2, 3, 4],[4, 5, 6, 7], [7, 8, 9, 10]])
数组的大小可以通过其shape属性获得:
>>> a.shape
(4,)
>>> c.shape
(3, 4)
使用数组的reshape方法,可以创建一个改变了尺寸的新数组,原数组的shape保持不变
数组的元素类型可以通过dtype属性获得


NumPy提供了很多专门用来创建数组的函数
arange函数类似于python的range函数,通过指定开始值、终值和步长来创建一维数组,注意
数组不包括终值
>>> np.arange(0,1,0.1)
array([ 0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9])
linspace函数通过指定开始值、终值和元素个数来创建一维数组,可以通过endpoint关键字指定
是否包括终值,缺省设置是包括终值
logspace函数和linspace类似,不过它创建等比数列
存取元素
>>> a = np.arange(10)
>>> a[5] # 用整数作为下标可以获取数组中的某个元素
5
>>> a[3:5] # 用范围作为下标获取数组的一个切片,包括a[3]不包括a[5]
array([3, 4])
>>> a[:5] # 省略开始下标,表示从a[0]开始
array([0, 1, 2, 3, 4])
>>> a[:-1] # 下标可以使用负数,表示从数组后往前数
array([0, 1, 2, 3, 4, 5, 6, 7, 8])
>>> a[2:4] = 100,101 # 下标还可以用来修改元素的值
>>> a
array([ 0, 1, 100, 101, 4, 5, 6, 7, 8, 9])
>>> a[1:-1:2] # 范围中的第三个参数表示步长,2表示隔一个元素取一个元素
array([ 1, 101, 5, 7])
>>> a[::-1] # 省略范围的开始下标和结束下标,步长为-1,整个数组头尾颠倒
array([ 9, 8, 7, 6, 5, 4, 101, 100, 1, 0])
>>> a[5:1:-2] # 步长为负数时,开始下标必须大于结束下标
array([ 5, 101])
>>> b = a[3:7] # 通过下标范围产生一个新的数组b,b和a共享同一块数据空间
>>> b
array([101, 4, 5, 6])
>>> b[2] = -10 # 将b的第2个元素修改为-10
>>> b
array([101, 4, -10, 6])
>>> a # a的第5个元素也被修改为10
array([ 0, 1, 100, 101, 4, -10, 6, 7, 8, 9])
使用整数序列
>>> x = np.arange(10,1,-1)
>>> x
array([10, 9, 8, 7, 6, 5, 4, 3, 2])
>>> x[[3, 3, 1, 8]] # 获取x中的下标为3, 3, 1, 8的4个元素,组成一个新的数组
array([7, 7, 9, 2])
>>> b = x[np.array([3,3,-3,8])] #下标可以是负数
>>> b[2] = 100
>>> b
array([7, 7, 100, 2])
>>> x # 由于b和x不共享数据空间,因此x中的值并没有改变
array([10, 9, 8, 7, 6, 5, 4, 3, 2])
>>> x[[3,5,1]] = -1, -2, -3 # 整数序列下标也可以用来修改元素的值
>>> x
array([10, -3, 8, -1, 6, -2, 4, 3, 2])
使用布尔数组
>>> x = np.arange(5,0,-1)
>>> x
array([5, 4, 3, 2, 1])
>>> x[np.array([True, False, True, False, False])]
>>> # 布尔数组中下标为0,2的元素为True,因此获取x中下标为0,2的元素
array([5, 3])
>>> x[[True, False, True, False, False]]
>>> # 如果是布尔列表,则把True当作1, False当作0,按照整数序列方式获取x中的元素
array([4, 5, 4, 5, 5])
>>> x[np.array([True, False, True, True])]
>>> # 布尔数组的长度不够时,不够的部分都当作False
array([5, 3, 2])
>>> x[np.array([True, False, True, True])] = -1, -2, -3
>>> # 布尔数组下标也可以用来修改元素
>>> x
array([-1, 4, -2, -3, 1])
多维数组
多维数组的存取和一维数组类似,因为多维数组有多个轴,因此它的下标需要用多个值来表示
结构数组
import numpy as np
persontype = np.dtype({
'names':['name', 'age', 'weight'],
'formats':['S32','i', 'f']})
a = np.array([("Zhang",32,75.5),("Wang",24,65.2)],
dtype=persontype)


2.ufunc运算
ufunc是universal function的缩写,它是一种能对数组的每个元素进行操作的函数。NumPy内置的许
多ufunc函数都是在C语言级别实现的,因此它们的计算速度非常快。
#-*- coding:utf-8 -*-
'''
Created on 2010-11-14

@author: afan
'''
import time
import math
import numpy as np
x = [i * 0.001 for i in xrange(1000000)]
start = time.clock()
for i, t in enumerate(x):
    x[i] = math.sin(t)
print "math.sin:", time.clock() - start
x = [i * 0.001 for i in xrange(1000000)]
x = np.array(x)
start = time.clock()
np.sin(x,x)
print "numpy.sin:", time.clock() - start
结果
math.sin: 0.438402455766
numpy.sin: 0.0422040139579
3.矩阵运算
matrix对象
numpy库提供了matrix类,使用matrix类创建的是矩阵对象,它们的加减乘除运算缺省采用矩阵
方式计算,因此用法和matlab十分类似。
矩阵的乘积可以使用dot函数进行计算。对于二维数组,它计算的是矩阵乘积,对于一维数组,它计算
的是其点积
4.文件存取
NumPy提供了多种文件操作函数方便我们存取数组内容。文件存取的格式分为两类:二进制和文本。
而二进制格式的文件又分为NumPy专用的格式化二进制类型和无格式类型。
使用数组的方法函数tofile可以方便地将数组中数据以二进制的格式写进文件。tofile输出的数据没有格
式,因此用numpy.fromfile读回来的时候需要自己格式化数据
>>> a = np.arange(0,12)
>>> a.shape = 3,4
>>> a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> a.tofile("a.bin")
>>> b = np.fromfile("a.bin", dtype=np.float) # 按照float类型读入数据
>>> b # 读入的数据是错误的
array([ 2.12199579e-314, 6.36598737e-314, 1.06099790e-313,
1.48539705e-313, 1.90979621e-313, 2.33419537e-313])
>>> a.dtype # 查看a的dtype
dtype('int32')
>>> b = np.fromfile("a.bin", dtype=np.int32) # 按照int32类型读入数据
>>> b # 数据是一维的
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
>>> b.shape = 3, 4 # 按照a的shape修改b的shape
>>> b # 这次终于正确了
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
matplotlib-绘制精美的图表
#-*- coding:utf-8 -*-
'''
Created on 2010-11-14

@author: afan
'''
import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 10, 1000)
y = np.sin(x)
z = np.cos(x**2)

plt.figure(figsize=(8,4))
plt.plot(x,y,label="$sin(x)$",color="red",linewidth=2)
plt.plot(x,z,"b--",label="$cos(x^2)$")
plt.xlabel("Time(s)")
plt.ylabel("Volt")
plt.title("PyPlot First Example")
plt.ylim(-1.2,1.2)
plt.legend()
plt.show()
绘制多轴图
一个绘图对象(figure)可以包含多个轴(axis),在Matplotlib中用轴表示一个绘图区域,可以将其理解
为子图。上面的第一个例子中,绘图对象只包括一个轴,因此只显示了一个轴(子图)。我们可以使用
subplot函数快速绘制有多个轴的图表。subplot函数的调用形式如下:
subplot(numRows, numCols, plotNum)









 Posted by at 6:59 下午
11月 152010
 

最近在用python处理字符串,经常用到正则表达式,觉得这个入门还是很不错的,与大家分享。

 

原文出处:http://www.amk.ca/python/howto/regex/

原文作者:A.M. Kuchling (amk@amk.ca

Abstract(摘要)

This document is an introductory tutorial to using regular expressions in Python with the re module. It provides a gentler introduction than the corresponding section in the Library Reference.
本文是通过Python的 re 模块来使用正则表达式的一个入门教程,和库参考手册的对应章节相比,更为浅显易懂、循序渐进。

This document is available from http://www.amk.ca/python/howto .
本文可以从 http://www.amk.ca/python/howto 捕获

Contents(目录)

 

目录

  1. Introduction(简介)
  2. Simple Patterns(简单模式)
    1. Matching Characters(字符匹配)
    2. Repeating Things(重复)
  3. Using Regular Expressions(使用正则表达式)
    1. Compiling Regular Expressions(编译正则表达式)
    2. The Backslash Plague(反斜杠的麻烦)
    3. Performing Matches(执行匹配)
    4. Module-Level Functions(模块级函数)
    5. Compilation Flags(编译标志)
  4. More Pattern Power(更多模式功能)
    1. More Metacharacters(更多的元字符)
    2. Grouping(分组)
    3. Non-capturing and Named Groups(无捕获组和命名组)
    4. Lookahead Assertions(前向界定符)
  5. Modifying Strings(修改字符串)
    1. Splitting Strings(将字符串分片)
    2. Search and Replace(搜索和替换)
  6. Common Problems(常见问题)
    1. Use String Methods(使用字符串方式)
    2. match() versus search()(match() vs search())
    3. Greedy versus Non-Greedy(贪婪 vs 不贪婪)
    4. Not Using re.VERBOSE(不用 re.VERBOSE)
  7. Feedback(反馈)
  8. About this document(关于本文档)

 

Introduction(简介)

The re module was added in Python 1.5, and provides Perl-style regular expression patterns. Earlier versions of Python came with the regex module, which provides Emacs-style patterns. Emacs-style patterns are slightly less readable and don't provide as many features, so there's not much reason to use the regex module when writing new code, though you might encounter old code that uses it.
Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式。Python 1.5之前版本则是通过 regex 模块提供 Emecs 风格的模式。Emacs 风格模式可读性稍差些,而且功能也不强,因此编写新代码时尽量不要再使用 regex 模块,当然偶尔你还是可能在老代码里发现其踪影。

Regular expressions (or REs) are essentially a tiny, highly specialized programming language embedded inside Python and made available through the re module. Using this little language, you specify the rules for the set of possible strings that you want to match; this set might contain English sentences, or e-mail addresses, or TeX commands, or anything you like. You can then ask questions such as "Does this string match the pattern?", or "Is there a match for the pattern anywhere in this string?". You can also use REs to modify a string or to split it apart in various ways.
就其本质而言,正则表达式(或 RE)是一种小型的、高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过 re 模块实现。使用这个小型语言,你可以为想要匹配的相应字符串集指定规则;该字符串集可能包含英文语句、e-mail地址、TeX命令或任何你想搞定的东西。然后你可以问诸如“这个字符串匹配该模式吗?”或“在这个字符串中是否有部分匹配该模式呢?”。你也可以使用 RE 以各种方式来修改或分割字符串。

Regular expression patterns are compiled into a series of bytecodes which are then executed by a matching engine written in C. For advanced use, it may be necessary to pay careful attention to how the engine will execute a given RE, and write the RE in a certain way in order to produce bytecode that runs faster. Optimization isn't covered in this document, because it requires that you have a good understanding of the matching engine's internals.
正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行。在高级用法中,也许还要仔细留意引擎是如何执行给定 RE ,如何以特定方式编写 RE 以令生产的字节码运行速度更快。本文并不涉及优化,因为那要求你已充分掌握了匹配引擎的内部机制。

The regular expression language is relatively small and restricted, so not all possible string processing tasks can be done using regular expressions. There are also tasks that can be done with regular expressions, but the expressions turn out to be very complicated. In these cases, you may be better off writing Python code to do the processing; while Python code will be slower than an elaborate regular expression, it will also probably be more understandable.
正则表达式语言相对小型和受限(功能有限),因此并非所有字符串处理都能用正则表达式完成。当然也有些任务可以用正则表达式完成,不过最终表达式会变得异常复杂。碰到这些情形时,编写 Python 代码进行处理可能反而更好;尽管 Python 代码比一个精巧的正则表达式要慢些,但它更易理解。

 

Simple Patterns(简单模式)

We'll start by learning about the simplest possible regular expressions. Since regular expressions are used to operate on strings, we'll begin with the most common task: matching characters.
我们将从最简单的正则表达式学习开始。由于正则表达式常用于字符串操作,那我们就从最常见的任务:字符匹配 下手。

For a detailed explanation of the computer science underlying regular expressions (deterministic and non-deterministic finite automata), you can refer to almost any textbook on writing compilers.
有关正则表达式底层的计算机科学上的详细解释(确定性和非确定性有限自动机),你可以查阅编写编译器相关的任何教科书。

 

1. Matching Characters(字符匹配)

Most letters and characters will simply match themselves. For example, the regular expression test will match the string "test" exactly. (You can enable a case-insensitive mode that would let this RE match "Test" or "TEST" as well; more about this later.)
大多数字母和字符一般都会和自身匹配。例如,正则表达式 test 会和字符串“test”完全匹配。(你也可以使用大小写不敏感模式,它还能让这个 RE 匹配“Test”或“TEST”;稍后会有更多解释。)

There are exceptions to this rule; some characters are special, and don't match themselves. Instead, they signal that some out-of-the-ordinary thing should be matched, or they affect other portions of the RE by repeating them. Much of this document is devoted to discussing various metacharacters and what they do.
这个规则当然会有例外;有些字符比较特殊,它们和自身并不匹配,而是会表明应和一些特殊的东西匹配,或者它们会影响到 RE 其它部分的重复次数。本文很大篇幅专门讨论了各种元字符及其作用。

Here's a complete list of the metacharacters; their meanings will be discussed in the rest of this HOWTO.
这里有一个元字符的完整列表;其含义会在本指南余下部分进行讨论。

. ^ $ * + ? { [ ] \ | ( )

The first metacharacters we'll look at are "[" and "]". They're used for specifying a character class, which is a set of characters that you wish to match. Characters can be listed individually, or a range of characters can be indicated by giving two characters and separating them by a "-". For example, [abc] will match any of the characters "a", "b", or "c"; this is the same as [a-c], which uses a range to express the same set of characters. If you wanted to match only lowercase letters, your RE would be [a-z].
我们首先考察的元字符是 "[" 和 "]"。它们常用来指定一个字符类别,所谓字符类别就是你想匹配的一个字符集。字符可以单个列出,也可以用“-”号分隔的两个给定字符来表示一个字符区间。例如,[abc] 将匹配"a", "b", 或 "c"中的任意一个字符;也可以用区间[a-c]来表示同一字符集,和前者效果一致。如果你只想匹配小写字母,那么 RE 应写成 [a-z]。

Metacharacters are not active inside classes. For example, [akm$] will match any of the characters "a", "k", "m", or "$"; "$" is usually a metacharacter, but inside a character class it's stripped of its special nature.
元字符在类别里并不起作用。例如,[akm$]将匹配字符"a", "k", "m", 或 "$" 中的任意一个;"$"通常用作元字符,但在字符类别里,其特性被除去,恢复成普通字符。

You can match the characters not within a range by complementing the set. This is indicated by including a "" as the first character of the class; `"" elsewhere will simply match the ""` character. For example, [5] will match any character except "5".
你可以用补集来匹配不在区间范围内的字符。其做法是把"^"作为类别的首个字符;其它地方的"^"只会简单匹配 "^" 字符本身。例如,[^5] 将匹配除 "5" 之外的任意字符。

Perhaps the most important metacharacter is the backslash, "\". As in Python string literals, the backslash can be followed by various characters to signal various special sequences. It's also used to escape all the metacharacters so you can still match them in patterns; for example, if you need to match a "[" or "\", you can precede them with a backslash to remove their special meaning: \[ or \\.
也许最重要的元字符是反斜杠"\"。 做为 Python 中的字符串字母,反斜杠后面可以加不同的字符以表示不同特殊意义。它也可以用于取消所有的元字符,这样你就可以在模式中匹配它们了。举个例子,如果你需要匹配字符 "[" 或 "\",你可以在它们之前用反斜杠来取消它们的特殊意义: \[ 或 \\。

Some of the special sequences beginning with "\" represent predefined sets of characters that are often useful, such as the set of digits, the set of letters, or the set of anything that isn't whitespace. The following predefined special sequences are available:
一些用 "\" 开始的特殊字符所表示的预定义字符集通常是很有用的,象数字集,字母集,或其它非空字符集。下列是可用的预设特殊字符:

\d

  • Matches any decimal digit; this is equivalent to the class [0-9].
    匹配任何十进制数;它相当于类 [0-9]。

\D

  • Matches any non-digit character; this is equivalent to the class [^0-9].
    匹配任何非数字字符;它相当于类 [^0-9]。

\s

  • Matches any whitespace character; this is equivalent to the class [ \t\n\r\f\v].
    匹配任何空白字符;它相当于类 [ \t\n\r\f\v]。

\S

  • Matches any non-whitespace character; this is equivalent to the class [^ \t\n\r\f\v].
    匹配任何非空白字符;它相当于类 [^ \t\n\r\f\v]。

\w

  • Matches any alphanumeric character; this is equivalent to the class [a-zA-Z0-9_].
    匹配任何字母数字字符;它相当于类 [a-zA-Z0-9_]。

\W

  • Matches any non-alphanumeric character; this is equivalent to the class [^a-zA-Z0-9_].
    匹配任何非字母数字字符;它相当于类 [^a-zA-Z0-9_]。

These sequences can be included inside a character class. For example, [\s,.] is a character class that will match any whitespace character, or "," or ".".
这样特殊字符都可以包含在一个字符类中。如,[\s,.]字符类将匹配任何空白字符或","或"."。

The final metacharacter in this section is .. It matches anything except a newline character, and there's an alternate mode (re.DOTALL) where it will match even a newline. "." is often used where you want to match any character.
本节最后一个元字符是 . 。它匹配除了换行字符外的任何字符,在 alternate 模式(re.DOTALL)下它甚至可以匹配换行。"." 通常被用于你想匹配“任何字符”的地方。

 

2. Repeating Things(重复)

 

 

Being able to match varying sets of characters is the first thing regular expressions can do that isn't already possible with the methods available on strings. However, if that was the only additional capability of regexes, they wouldn't be much of an advance. Another capability is that you can specify that portions of the RE must be repeated a certain number of times.
正则表达式第一件能做的事是能够匹配不定长的字符集,而这是其它能作用在字符串上的方法所不能做到的。 不过,如果那是正则表达式唯一的附加功能的话,那么它们也就不那么优秀了。它们的另一个功能就是你可以指定正则表达式的一部分的重复次数。

The first metacharacter for repeating things that we'll look at is *. * doesn't match the literal character "*"; instead, it specifies that the previous character can be matched zero or more times, instead of exactly once.
我们讨论的第一个重复功能的元字符是 *。* 并不匹配字母字符 "*";相反,它指定前一个字符可以被匹配零次或更多次,而不是只有一次。

For example, ca*t will match "ct" (0 "a"characters), "cat" (1 "a"), "caaat" (3 "a"characters), and so forth. The RE engine has various internal limitations stemming from the size of C's int type, that will prevent it from matching over 2 billion "a" characters; you probably don't have enough memory to construct a string that large, so you shouldn't run into that limit.
举个例子,ca*t 将匹配 "ct" (0 个 "a" 字符), "cat" (1 个 "a"), "caaat" (3 个 "a" 字符)等等。RE 引擎有各种来自 C 的整数类型大小的内部限制,以防止它匹配超过2亿个 "a" 字符;你也许没有足够的内存去建造那么大的字符串,所以将不会累计到那个限制。

Repetitions such as * are greedy; when repeating a RE, the matching engine will try to repeat it as many times as possible. If later portions of the pattern don't match, the matching engine will then back up and try again with few repetitions.
象 * 这样地重复是“贪婪的”;当重复一个 RE 时,匹配引擎会试着重复尽可能多的次数。如果模式的后面部分没有被匹配,匹配引擎将退回并再次尝试更小的重复。

A step-by-step example will make this more obvious. Let's consider the expression a[bcd]*b. This matches the letter "a", zero or more letters from the class [bcd], and finally ends with a "b". Now imagine matching this RE against the string "abcbd".
一步步的示例可以使它更加清晰。让我们考虑表达式 a[bcd]*b。它匹配字母 "a",零个或更多个来自类 [bcd]中的字母,最后以 "b" 结尾。现在想一想该 RE 对字符串 "abcbd" 的匹配。

Step

Matched

Explanation

1

a

The a in the RE matches.
a 匹配模式

2

abcbd

The engine matches [bcd]*, going as far as it can, which is to the end of the string.
引擎匹配 [bcd]*,并尽其所能匹配到字符串的结尾

3

Failure

The engine tries to match b, but the current position is at the end of the string, so it fails.
引擎尝试匹配 b,但当前位置已经是字符的最后了,所以失败

4

abcb

Back up, so that [bcd]* matches one less character.
退回,[bcd]*尝试少匹配一个字符。

5

Failure

Try b again, but the current position is at the last character, which is a "d".
再次尝次b,但在当前最后一位字符是"d"。

6

abc

Back up again, so that [bcd]* is only matching "bc".
再次退回,[bcd]*只匹配 "bc"。

7

abcb

Try b again. This time but the character at the current position is "b", so it succeeds.
再次尝试 b ,这次当前位上的字符正好是 "b"

The end of the RE has now been reached, and it has matched "abcb". This demonstrates how the matching engine goes as far as it can at first, and if no match is found it will then progressively back up and retry the rest of the RE again and again. It will back up until it has tried zero matches for [bcd]*, and if that subsequently fails, the engine will conclude that the string doesn't match the RE at all.
RE 的结尾部分现在可以到达了,它匹配 "abcb"。这证明了匹配引擎一开始会尽其所能进行匹配,如果没有匹配然后就逐步退回并反复尝试 RE 剩下来的部分。直到它退回尝试匹配 [bcd] 到零次为止,如果随后还是失败,那么引擎就会认为该字符串根本无法匹配 RE 。

Another repeating metacharacter is +, which matches one or more times. Pay careful attention to the difference between * and +; * matches zero or more times, so whatever's being repeated may not be present at all, while + requires at least one occurrence. To use a similar example, ca+t will match "cat" (1 "a"), "caaat" (3 "a"'s), but won't match "ct".
另一个重复元字符是 +,表示匹配一或更多次。请注意 * 和 + 之间的不同;* 匹配零或更多次,所以根本就可以不出现,而 + 则要求至少出现一次。用同一个例子,ca+t 就可以匹配 "cat" (1 个 "a"), "caaat" (3 个 "a"), 但不能匹配 "ct"。

There are two more repeating qualifiers. The question mark character, ?, matches either once or zero times; you can think of it as marking something as being optional. For example, home-?brew matches either "homebrew" or "home-brew".
还有更多的限定符。问号 ? 匹配一次或零次;你可以认为它用于标识某事物是可选的。例如:home-?brew 匹配 "homebrew" 或 "home-brew"。

The most complicated repeated qualifier is {m,n}, where m and n are decimal integers. This qualifier means there must be at least m repetitions, and at most n. For example, a/{1,3}b will match "a/b", "a//b", and "a///b". It won't match "ab", which has no slashes, or "a////b", which has four.
最复杂的重复限定符是 {m,n},其中 m 和 n 是十进制整数。该限定符的意思是至少有 m 个重复,至多到 n 个重复。举个例子,a/{1,3}b 将匹配 "a/b","a//b" 和 "a///b"。它不能匹配 "ab" 因为没有斜杠,也不能匹配 "a////b" ,因为有四个。

You can omit either m or n; in that case, a reasonable value is assumed for the missing value. Omitting m is interpreted as a lower limit of 0, while omitting n results in an upper bound of infinity -- actually, the 2 billion limit mentioned earlier, but that might as well be infinity.
你可以忽略 m 或 n;因为会为缺失的值假设一个合理的值。忽略 m 会认为下边界是 0,而忽略 n 的结果将是上边界为无穷大 -- 实际上是先前我们提到的 2 兆,但这也许同无穷大一样。

Readers of a reductionist bent may notice that the three other qualifiers can all be expressed using this notation. {0,} is the same as *, {1,} is equivalent to +, and {0,1} is the same as ?. It's better to use *, +, or ? when you can, simply because they're shorter and easier to read.
细心的读者也许注意到其他三个限定符都可以用这样方式来表示。 {0,} 等同于 *,{1,} 等同于 +,而{0,1}则与 ? 相同。如果可以的话,最好使用 *,+,或?。很简单因为它们更短也再容易懂。

 

Using Regular Expressions(使用正则表达式)

Now that we've looked at some simple regular expressions, how do we actually use them in Python? The re module provides an interface to the regular expression engine, allowing you to compile REs into objects and then perform matches with them.
现在我们已经看了一些简单的正则表达式,那么我们实际在 Python 中是如何使用它们的呢? re 模块提供了一个正则表达式引擎的接口,可以让你将 REs 编译成对象并用它们来进行匹配。

 

1. Compiling Regular Expressions(编译正则表达式)

Regular expressions are compiled into RegexObject instances, which have methods for various operations such as searching for pattern matches or performing string substitutions.
正则表达式被编译成 RegexObject 实例,可以为不同的操作提供方法,如模式匹配搜索或字符串替换。

切换行号显示 切换行号显示 切换行号显示
   1 >>> import re
   2 >>> p = re.compile('ab*')
   3 >>> print p
   4 <re.RegexObject instance at 80b4150>

re.compile() also accepts an optional flags argument, used to enable various special features and syntax variations. We'll go over the available settings later, but for now a single example will do:
re.compile() 也接受可选的标志参数,常用来实现不同的特殊功能和语法变更。我们稍后将查看所有可用的设置,但现在只举一个例子:

切换行号显示 切换行号显示 切换行号显示
   1 >>> p = re.compile('ab*', re.IGNORECASE)

The RE is passed to re.compile() as a string. REs are handled as strings because regular expressions aren't part of the core Python language, and no special syntax was created for expressing them. (There are applications that don't need REs at all, so there's no need to bloat the language specification by including them.) Instead, the re module is simply a C extension module included with Python, just like the socket or zlib module.
RE 被做为一个字符串发送给 re.compile()。REs 被处理成字符串是因为正则表达式不是 Python 语言的核心部分,也没有为它创建特定的语法。(应用程序根本就不需要 REs,因此没必要包含它们去使语言说明变得臃肿不堪。)而 re 模块则只是以一个 C 扩展模块的形式来被 Python 包含,就象 socket 或 zlib 模块一样。

Putting REs in strings keeps the Python language simpler, but has one disadvantage which is the topic of the next section.
将 REs 作为字符串以保证 Python 语言的简洁,但这样带来的一个麻烦就是象下节标题所讲的。

 

2. The Backslash Plague(反斜杠的麻烦)

As stated earlier, regular expressions use the backslash character ("\") to indicate special forms or to allow special characters to be used without invoking their special meaning. This conflicts with Python's usage of the same character for the same purpose in string literals.
在早期规定中,正则表达式用反斜杠字符 ("\") 来表示特殊格式或允许使用特殊字符而不调用它的特殊用法。这就与 Python 在字符串中的那些起相同作用的相同字符产生了冲突。

Let's say you want to write a RE that matches the string "\section", which might be found in a LATEX file. To figure out what to write in the program code, start with the desired string to be matched. Next, you must escape any backslashes and other metacharacters by preceding them with a backslash, resulting in the string "\\section". The resulting string that must be passed to re.compile() must be \\section. However, to express this as a Python string literal, both backslashes must be escaped again.
让我们举例说明,你想写一个 RE 以匹配字符串 "\section",可能是在一个 LATEX 文件查找。为了要在程序代码中判断,首先要写出想要匹配的字符串。接下来你需要在所有反斜杠和元字符前加反斜杠来取消其特殊意义。

Characters(字符)

Stage(阶段)

\section

Text string to be matched(要匹配的字符串)

\\section

Escaped backslash for re.compile(为 re.compile 取消反斜杠的特殊意义)

"\\\\section"

Escaped backslashes for a string literal(为字符串取消反斜杠)

In short, to match a literal backslash, one has to write '\\\\' as the RE string, because the regular expression must be "\\", and each backslash must be expressed as "\\" inside a regular Python string literal. In REs that feature backslashes repeatedly, this leads to lots of repeated backslashes and makes the resulting strings difficult to understand.
简单地说,为了匹配一个反斜杠,不得不在 RE 字符串中写 '\\\\',因为正则表达式中必须是 "\\",而每个反斜杠按 Python 字符串字母表示的常规必须表示成 "\\"。在 REs 中反斜杠的这个重复特性会导致大量重复的反斜杠,而且所生成的字符串也很难懂。

The solution is to use Python's raw string notation for regular expressions; backslashes are not handled in any special way in a string literal prefixed with "r", so r"\n" is a two-character string containing "\" and "n", while "\n" is a one-character string containing a newline. Frequently regular expressions will be expressed in Python code using this raw string notation.
解决的办法就是为正则表达式使用 Python 的 raw 字符串表示;在字符串前加个 "r" 反斜杠就不会被任何特殊方式处理,所以 r"\n" 就是包含"\" 和 "n" 的两个字符,而 "\n" 则是一个字符,表示一个换行。正则表达式通常在 Python 代码中都是用这种 raw 字符串表示。

Regular String(常规字符串)

Raw string(Raw 字符串)

"ab*"

r"ab*"

"\\\\section"

r"\\section"

"\\w+\\s+\\1"

r"\w+\s+\1"

 

3. Performing Matches(执行匹配)

Once you have an object representing a compiled regular expression, what do you do with it? RegexObject instances have several methods and attributes. Only the most significant ones will be covered here; consult the Library Reference for a complete listing.
一旦你有了已经编译了的正则表达式的对象,你要用它做什么呢?RegexObject 实例有一些方法和属性。这里只显示了最重要的几个,如果要看完整的列表请查阅 Library Refference。

Method/Attribute(方法/属性)

Purpose(作用)

match()

Determine if the RE matches at the beginning of the string.
决定 RE 是否在字符串刚开始的位置匹配

search()

Scan through a string, looking for any location where this RE matches.
扫描字符串,找到这个 RE 匹配的位置

findall()

Find all substrings where the RE matches, and returns them as a list.
找到 RE 匹配的所有子串,并把它们作为一个列表返回

finditer()

Find all substrings where the RE matches, and returns them as an iterator.
找到 RE 匹配的所有子串,并把它们作为一个迭代器返回

match() and search() return None if no match can be found. If they're successful, a MatchObject instance is returned, containing information about the match: where it starts and ends, the substring it matched, and more.
如果没有匹配到的话,match() 和 search() 将返回 None。如果成功的话,就会返回一个 MatchObject 实例,其中有这次匹配的信息:它是从哪里开始和结束,它所匹配的子串等等。

You can learn about this by interactively experimenting with the re module. If you have Tkinter available, you may also want to look at Tools/scripts/redemo.py, a demonstration program included with the Python distribution. It allows you to enter REs and strings, and displays whether the RE matches or fails. redemo.py can be quite useful when trying to debug a complicated RE. Phil Schwartz's Kodos is also an interactive tool for developing and testing RE patterns. This HOWTO will use the standard Python interpreter for its examples.
你可以用采用人机对话并用 re 模块实验的方式来学习它。如果你有 Tkinter 的话,你也许可以考虑参考一下 Tools/scripts/redemo.py,一个包含在 Python 发行版里的示范程序。

First, run the Python interpreter, import the re module, and compile a RE:
首先,运行 Python 解释器,导入 re 模块并编译一个 RE:

切换行号显示 切换行号显示 切换行号显示
   1 Python 2.2.2 (#1, Feb 10 2003, 12:57:01)
   2 >>> import re
   3 >>> p = re.compile('[a-z]+')
   4 >>> p
   5 <_sre.SRE_Pattern object at 80c3c28>
ERROR: EOF in multi-line statement

Now, you can try matching various strings against the RE [a-z]+. An empty string shouldn't match at all, since + means 'one or more repetitions'. match() should return None in this case, which will cause the interpreter to print no output. You can explicitly print the result of match() to make this clear.
现在,你可以试着用 RE 的 [a-z]+ 去匹配不同的字符串。一个空字符串将根本不能匹配,因为 + 的意思是 “一个或更多的重复次数”。 在这种情况下 match() 将返回 None,因为它使解释器没有输出。你可以明确地打印出 match() 的结果来弄清这一点。

切换行号显示 切换行号显示 切换行号显示
   1 >>> p.match("")
   2 >>> print p.match("")
   3 None

Now, let's try it on a string that it should match, such as "tempo". In this case, match() will return a MatchObject, so you should store the result in a variable for later use.
现在,让我们试着用它来匹配一个字符串,如 "tempo"。这时,match() 将返回一个 MatchObject。因此你可以将结果保存在变量里以便后面使用。

切换行号显示 切换行号显示 切换行号显示
   1 >>> m = p.match( 'tempo')
   2 >>> print m
   3 <_sre.SRE_Match object at 80c4f68>

Now you can query the MatchObject for information about the matching string. MatchObject instances also have several methods and attributes; the most important ones are:
现在你可以查询 MatchObject 关于匹配字符串的相关信息了。MatchObject 实例也有几个方法和属性;最重要的那些如下所示:

Method/Attribute(方法/属性)

Purpose(作用)

group()

Return the string matched by the RE
返回被 RE 匹配的字符串

start()

Return the starting position of the match
返回匹配开始的位置

end()

Return the ending position of the match
返回匹配结束的位置

span()

Return a tuple containing the (start, end) positions of the match
返回一个元组包含匹配 (开始,结束) 的位置

Trying these methods will soon clarify their meaning:
试试这些方法不久就会清楚它们的作用了:

切换行号显示 切换行号显示 切换行号显示
   1 >>> m.group()
   2 'tempo'
   3 >>> m.start(), m.end()
   4 (0, 5)
   5 >>> m.span()
   6 (0, 5)

group() returns the substring that was matched by the RE. start() and end() return the starting and ending index of the match. span() returns both start and end indexes in a single tuple. Since the match method only checks if the RE matches at the start of a string, start() will always be zero. However, the search method of RegexObject instances scans through the string, so the match may not start at zero in that case.
group() 返回 RE 匹配的子串。start() 和 end() 返回匹配开始和结束时的索引。span() 则用单个元组把开始和结束时的索引一起返回。因为匹配方法检查到如果 RE 在字符串开始处开始匹配,那么 start() 将总是为零。然而, RegexObject 实例的 search 方法扫描下面的字符串的话,在这种情况下,匹配开始的位置就也许不是零了。

切换行号显示 切换行号显示 切换行号显示
   1 >>> print p.match('::: message')
   2 None
   3 >>> m = p.search('::: message') ; print m
   4 <re.MatchObject instance at 80c9650>
   5 >>> m.group()
   6 'message'
   7 >>> m.span()
   8 (4, 11)

In actual programs, the most common style is to store the MatchObject in a variable, and then check if it was None. This usually looks like:
在实际程序中,最常见的作法是将 MatchObject 保存在一个变量里,然后检查它是否为 None,通常如下所示:

切换行号显示 切换行号显示 切换行号显示
   1 p = re.compile( ... )
   2 m = p.match( 'string goes here' )
   3 if m:
   4     print 'Match found: ', m.group()
   5 else:
   6     print 'No match'

Two RegexObject methods return all of the matches for a pattern. findall() returns a list of matching strings:
两个 RegexObject 方法返回所有匹配模式的子串。findall()返回一个匹配字符串列表:

切换行号显示 切换行号显示 切换行号显示
   1 >>> p = re.compile('\d+')
   2 >>> p.findall('12 drummers drumming, 11 pipers piping, 10 lords a-leaping')
   3 ['12', '11', '10']

findall() has to create the entire list before it can be returned as the result. In Python 2.2, the finditer() method is also available, returning a sequence of MatchObject instances as an iterator.
findall() 在它返回结果时不得不创建一个列表。在 Python 2.2中,也可以用 finditer() 方法。

切换行号显示 切换行号显示 切换行号显示
   1 >>> iterator = p.finditer('12 drummers drumming, 11 ... 10 ...')
   2 >>> iterator
   3 <callable-iterator object at 0x401833ac>
   4 >>> for match in iterator:
   5 ...     print match.span()
   6 ...
   7 (0, 2)
   8 (22, 24)
   9 (29, 31)

 

4. Module-Level Functions(模块级函数)

You don't have to produce a RegexObject and call its methods; the re module also provides top-level functions called match(), search(), sub(), and so forth. These functions take the same arguments as the corresponding RegexObject method, with the RE string added as the first argument, and still return either None or a MatchObject instance.
你不一定要产生一个 RegexObject 对象然后再调用它的方法;re 模块也提供了顶级函数调用如 match()、search()、sub() 等等。这些函数使用 RE 字符串作为第一个参数,而后面的参数则与相应 RegexObject 的方法参数相同,返回则要么是 None 要么就是一个 MatchObject 的实例。

切换行号显示 切换行号显示 切换行号显示
   1 >>> print re.match(r'From\s+', 'Fromage amk')
   2 None
   3 >>> re.match(r'From\s+', 'From amk Thu May 14 19:12:10 1998')
   4 <re.MatchObject instance at 80c5978>

Under the hood, these functions simply produce a RegexObject for you and call the appropriate method on it. They also store the compiled object in a cache, so future calls using the same RE are faster.
Under the hood, 这些函数简单地产生一个 RegexOject 并在其上调用相应的方法。它们也在缓存里保存编译后的对象,因此在将来调用用到相同 RE 时就会更快。

Should you use these module-level functions, or should you get the RegexObject and call its methods yourself? That choice depends on how frequently the RE will be used, and on your personal coding style. If a RE is being used at only one point in the code, then the module functions are probably more convenient. If a program contains a lot of regular expressions, or re-uses the same ones in several locations, then it might be worthwhile to collect all the definitions in one place, in a section of code that compiles all the REs ahead of time. To take an example from the standard library, here's an extract from xmllib.py: 你将使用这些模块级函数,还是先得到一个 RegexObject 再调用它的方法呢?如何选择依赖于怎样用 RE 更有效率以及你个人编码风格。如果一个 RE 在代码中只做用一次的话,那么模块级函数也许更方便。如果程序包含很多的正则表达式,或在多处复用同一个的话,那么将全部定义放在一起,在一段代码中提前编译所有的 REs 更有用。从标准库中看一个例子,这是从 xmllib.py 文件中提取出来的:

切换行号显示 切换行号显示 切换行号显示
   1 ref = re.compile( ... )
   2 entityref = re.compile( ... )
   3 charref = re.compile( ... )
   4 starttagopen = re.compile( ... )

I generally prefer to work with the compiled object, even for one-time uses, but few people will be as much of a purist about this as I am.
我通常更喜欢使用编译对象,甚至它只用一次,but few people will be as much of a purist about this as I am。

 

5. Compilation Flags(编译标志)

Compilation flags let you modify some aspects of how regular expressions work. Flags are available in the re module under two names, a long name such as IGNORECASE, and a short, one-letter form such as I. (If you're familiar with Perl's pattern modifiers, the one-letter forms use the same letters; the short form of re.VERBOSE is re.X, for example.) Multiple flags can be specified by bitwise OR-ing them; re.I | re.M sets both the I and M flags, for example.
编译标志让你可以修改正则表达式的一些运行方式。在 re 模块中标志可以使用两个名字,一个是全名如 IGNORECASE,一个是缩写,一字母形式如 I。(如果你熟悉 Perl 的模式修改,一字母形式使用同样的字母;例如 re.VERBOSE的缩写形式是 re.X。)多个标志可以通过按位 OR-ing 它们来指定。如 re.I | re.M 被设置成 I 和 M 标志:

Here's a table of the available flags, followed by a more detailed explanation of each one.
这有个可用标志表,对每个标志后面都有详细的说明。

Flag(标志)

Meaning(含义)

DOTALL, S

Make . match any character, including newlines
使 . 匹配包括换行在内的所有字符

IGNORECASE, I

Do case-insensitive matches
使匹配对大小写不敏感

LOCALE, L

Do a locale-aware match
做本地化识别(locale-aware)匹配

MULTILINE, M

Multi-line matching, affecting and $[[BR]]多行匹配,影响 和 $

VERBOSE, X

Enable verbose REs, which can be organized more cleanly and understandably.
能够使用 REs 的 verbose 状态,使之被组织得更清晰易懂

I
IGNORECASE

  • Perform case-insensitive matching; character class and literal strings will match letters by ignoring case. For example, [A-Z] will match lowercase letters, too, and Spam will match "Spam", "spam", or "spAM". This lowercasing doesn't take the current locale into account; it will if you also set the LOCALE flag.
    使匹配对大小写不敏感;字符类和字符串匹配字母时忽略大小写。举个例子,[A-Z]也可以匹配小写字母,Spam 可以匹配 "Spam", "spam", 或 "spAM"。这个小写字母并不考虑当前位置。

L
LOCALE

  • Make \w, \W, \b, and \B, dependent on the current locale.
    影响 \w, \W, \b, 和 \B,这取决于当前的本地化设置。

    Locales are a feature of the C library intended to help in writing programs that take account of language differences. For example, if you're processing French text, you'd want to be able to write \w+ to match words, but \w only matches the character class [A-Za-z]; it won't match "é" or "ç". If your system is configured properly and a French locale is selected, certain C functions will tell the program that "é" should also be considered a letter. Setting the LOCALE flag when compiling a regular expression will cause the resulting compiled object to use these C functions for \w; this is slower, but also enables \w+ to match French words as you'd expect.
    locales 是 C 语言库中的一项功能,是用来为需要考虑不同语言的编程提供帮助的。举个例子,如果你正在处理法文文本,你想用 \w+ 来匹配文字,但 \w 只匹配字符类 [A-Za-z];它并不能匹配 "é" 或 "ç"。如果你的系统配置适当且本地化设置为法语,那么内部的 C 函数将告诉程序 "é" 也应该被认为是一个字母。当在编译正则表达式时使用 LOCALE 标志会得到用这些 C 函数来处理 \w 后的编译对象;这会更慢,但也会象你希望的那样可以用 \w+ 来匹配法文文本。

M
MULTILINE

  • (^ and $ haven't been explained yet; they'll be introduced in section 4.1.)
    (此时 ^ 和 $ 不会被解释; 它们将在 4.1 节被介绍.)

    Usually matches only at the beginning of the string, and $ matches only at the end of the string and immediately before the newline (if any) at the end of the string. When this flag is specified, matches at the beginning of the string and at the beginning of each line within the string, immediately following each newline. Similarly, the $ metacharacter matches either at the end of the string and at the end of each line (immediately preceding each newline).
    使用 只匹配字符串的开始,而 $ 则只匹配字符串的结尾和直接在换行前(如果有的话)的字符串结尾。当本标志指定后, 匹配字符串的开始和字符串中每行的开始。同样的, $ 元字符匹配字符串结尾和字符串中每行的结尾(直接在每个换行之前)。

S
DOTALL

  • Makes the "." special character match any character at all, including a newline; without this flag, "." will match anything except a newline.
    使 "." 特殊字符完全匹配任何字符,包括换行;没有这个标志, "." 匹配除了换行外的任何字符。

X
VERBOSE

  • This flag allows you to write regular expressions that are more readable by granting you more flexibility in how you can format them. When this flag has been specified, whitespace within the RE string is ignored, except when the whitespace is in a character class or preceded by an d backslash; this lets you organize and indent the RE more clearly. It also enables you to put comments within a RE that will be ignored by the engine; comments are marked by a "#" that's neither in a character class or preceded by an d backslash.
    该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。当该标志被指定时,在 RE 字符串中的空白符被忽略,除非该空白符在字符类中或在反斜杠之后;这可以让你更清晰地组织和缩进 RE。它也可以允许你将注释写入 RE,这些注释会被引擎忽略;注释用 "#"号 来标识,不过该符号不能在字符串或反斜杠之后。

    For example, here's a RE that uses re.VERBOSE; see how much easier it is to read?
    举个例子,这里有一个使用 re.VERBOSE 的 RE;看看读它轻松了多少?

    切换行号显示 切换行号显示 切换行号显示
       1 charref = re.compile(r"""
           2  &[#]                # Start of a numeric entity reference
           3  (
           4    [0-9]+[^0-9]      # Decimal form
           5    | 0[0-7]+[^0-7]   # Octal form
           6    | x[0-9a-fA-F]+[^0-9a-fA-F] # Hexadecimal form
           7  )
           8 """, re.VERBOSE)
        
    

    Without the verbose setting, the RE would look like this:
    没有 verbose 设置, RE 会看起来象这样:

    切换行号显示 切换行号显示 切换行号显示
       1 charref = re.compile("&#([0-9]+[^0-9]"
           2                      "|0[0-7]+[^0-7]"
           3                      "|x[0-9a-fA-F]+[^0-9a-fA-F])")
        
    

    In the above example, Python's automatic concatenation of string literals has been used to break up the RE into smaller pieces, but it's still more difficult to understand than the version using re.VERBOSE.
    在上面的例子里,Python 的字符串自动连接可以用来将 RE 分成更小的部分,但它比用 re.VERBOSE 标志时更难懂。

 

More Pattern Power(更多模式功能)

So far we've only covered a part of the features of regular expressions. In this section, we'll cover some new metacharacters, and how to use groups to retrieve portions of the text that was matched.
到目前为止,我们只展示了正则表达式的一部分功能。在本节,我们将展示一些新的元字符和如何使用组来检索被匹配的文本部分。

 

1. More Metacharacters(更多的元字符)

There are some metacharacters that we haven't covered yet. Most of them will be covered in this section.
还有一些我们还没展示的元字符,其中的大部分将在本节展示。

Some of the remaining metacharacters to be discussed are zero-width assertions. They don't cause the engine to advance through the string; instead, they consume no characters at all, and simply succeed or fail. For example, \b is an assertion that the current position is located at a word boundary; the position isn't changed by the \b at all. This means that zero-width assertions should never be repeated, because if they match once at a given location, they can obviously be matched an infinite number of times.
剩下来要讨论的一部分元字符是零宽界定符(zero-width assertions)。它们并不会使引擎在处理字符串时更快;相反,它们根本就没有对应任何字符,只是简单的成功或失败。举个例子, \b 是一个在单词边界定位当前位置的界定符(assertions),这个位置根本就不会被 \b 改变。这意味着零宽界定符(zero-width assertions)将永远不会被重复,因为如果它们在给定位置匹配一次,那么它们很明显可以被匹配无数次。

|

  • Alternation, or the "or" operator. If A and B are regular expressions, A|B will match any string that matches either "A" or "B". | has very low precedence in order to make it work reasonably when you're alternating multi-character strings. Crow|Servo will match either "Crow" or "Servo", not "Cro", a "w" or an "S", and "ervo".
    可选项,或者 "or" 操作符。如果 A 和 B 是正则表达式,A|B 将匹配任何匹配了 "A" 或 "B" 的字符串。| 的优先级非常低,是为了当你有多字符串要选择时能适当地运行。Crow|Servo 将匹配"Crow" 或 "Servo", 而不是 "Cro", 一个 "w" 或 一个 "S", 和 "ervo"。

    To match a literal "|", use \|, or enclose it inside a character class, as in [|].
    为了匹配字母 "|",可以用 \|,或将其包含在字符类中,如[|]。

^

  • Matches at the beginning of lines. Unless the MULTILINE flag has been set, this will only match at the beginning of the string. In MULTILINE mode, this also matches immediately after each newline within the string.
    匹配行首。除非设置 MULTILINE 标志,它只是匹配字符串的开始。在 MULTILINE 模式里,它也可以直接匹配字符串中的每个换行。

    For example, if you wish to match the word "From" only at the beginning of a line, the RE to use is ^From.
    例如,如果你只希望匹配在行首单词 "From",那么 RE 将用 ^From。

    切换行号显示 切换行号显示 切换行号显示
       1 >>> print re.search('^From', 'From Here to Eternity')
           2 <re.MatchObject instance at 80c1520>
           3 >>> print re.search('^From', 'Reciting From Memory')
           4 None
        
    

$

  • Matches at the end of a line, which is defined as either the end of the string, or any location followed by a newline character.
    匹配行尾,行尾被定义为要么是字符串尾,要么是一个换行字符后面的任何位置。

    切换行号显示 切换行号显示 切换行号显示
       1 >>> print re.search('}$', '{block}')
           2 <re.MatchObject instance at 80adfa8>
           3 >>> print re.search('}$', '{block} ')
           4 None
           5 >>> print re.search('}$', '{block}\n')
           6 <re.MatchObject instance at 80adfa8>
        
    

    To match a literal "$", use \$ or enclose it inside a character class, as in [$].
    匹配一个 "$",使用 \$ 或将其包含在字符类中,如[$]。

\A

  • Matches only at the start of the string. When not in MULTILINE mode, \A and are effectively the same. In MULTILINE mode, however, they're different; \A still matches only at the beginning of the string, but may match at any location inside the string that follows a newline character.
    只匹配字符串首。当不在 MULTILINE 模式,\A 和 实际上是一样的。然而,在 MULTILINE 模式里它们是不同的;\A 只是匹配字符串首,而 还可以匹配在换行符之后字符串的任何位置。

\Z

  • Matches only at the end of the string.
    只匹配字符串尾。

\b

  • Word boundary. This is a zero-width assertion that matches only at the beginning or end of a word. A word is defined as a sequence of alphanumeric characters, so the end of a word is indicated by whitespace or a non-alphanumeric character.
    单词边界。这是个零宽界定符(zero-width assertions)只用以匹配单词的词首和词尾。单词被定义为一个字母数字序列,因此词尾就是用空白符或非字母数字符来标示的。

    The following example matches "class" only when it's a complete word; it won't match when it's contained inside another word.
    下面的例子只匹配 "class" 整个单词;而当它被包含在其他单词中时不匹配。

    切换行号显示 切换行号显示 切换行号显示
       1 >>> p = re.compile(r'\bclass\b')
           2 >>> print p.search('no class at all')
           3 <re.MatchObject instance at 80c8f28>
           4 >>> print p.search('the declassified algorithm')
           5 None
           6 >>> print p.search('one subclass is')
           7 None
        
    

    There are two subtleties you should remember when using this special sequence. First, this is the worst collision between Python's string literals and regular expression sequences. In Python's string literals, "\b" is the backspace character, ASCII value 8. If you're not using raw strings, then Python will convert the "\b" to a backspace, and your RE won't match as you expect it to. The following example looks the same as our previous RE, but omits the "r" in front of the RE string.
    当用这个特殊序列时你应该记住这里有两个微妙之处。第一个是 Python 字符串和正则表达式之间最糟的冲突。在 Python 字符串里,"\b" 是反斜杠字符,ASCII值是8。如果你没有使用 raw 字符串时,那么 Python 将会把 "\b" 转换成一个回退符,你的 RE 将无法象你希望的那样匹配它了。下面的例子看起来和我们前面的 RE 一样,但在 RE 字符串前少了一个 "r" 。

    切换行号显示 切换行号显示 切换行号显示
       1 >>> p = re.compile('\bclass\b')
           2 >>> print p.search('no class at all')
           3 None
           4 >>> print p.search('\b' + 'class' + '\b')
           5 <re.MatchObject instance at 80c3ee0>
        
    

    Second, inside a character class, where there's no use for this assertion, \b represents the backspace character, for compatibility with Python's string literals.
    第二个在字符类中,这个限定符(assertion)不起作用,\b 表示回退符,以便与 Python 字符串兼容。

\B

  • Another zero-width assertion, this is the opposite of \b, only matching when the current position is not at a word boundary.
    另一个零宽界定符(zero-width assertions),它正好同 \b 相反,只在当前位置不在单词边界时匹配。

 

2. Grouping(分组)

Frequently you need to obtain more information than just whether the RE matched or not. Regular expressions are often used to dissect strings by writing a RE divided into several subgroups which match different components of interest. For example, an RFC-822 header line is divided into a header name and a value, separated by a ":". This can be handled by writing a regular expression which matches an entire header line, and has one group which matches the header name, and another group which matches the header's value.
你经常需要得到比 RE 是否匹配还要多的信息。正则表达式常常用来分析字符串,编写一个 RE 匹配感兴趣的部分并将其分成几个小组。举个例子,一个 RFC-822 的头部用 ":" 隔成一个头部名和一个值,这就可以通过编写一个正则表达式匹配整个头部,用一组匹配头部名,另一组匹配头部值的方式来处理。

Groups are marked by the "(", ")" metacharacters. "(" and ")" have much the same meaning as they do in mathematical expressions; they group together the expressions contained inside them. For example, you can repeat the contents of a group with a repeating qualifier, such as *, +, ?, or {m,n}. For example, (ab)* will match zero or more repetitions of "ab".
组是通过 "(" 和 ")" 元字符来标识的。 "(" 和 ")" 有很多在数学表达式中相同的意思;它们一起把在它们里面的表达式组成一组。举个例子,你可以用重复限制符,象 *, +, ?, 和 {m,n},来重复组里的内容,比如说(ab)* 将匹配零或更多个重复的 "ab"。

切换行号显示 切换行号显示 切换行号显示
   1 >>> p = re.compile('(ab)*')
   2 >>> print p.match('ababababab').span()
   3 (0, 10)

Groups indicated with "(", ")" also capture the starting and ending index of the text that they match; this can be retrieved by passing an argument to group(), start(), end(), and span(). Groups are numbered starting with 0. Group 0 is always present; it's the whole RE, so MatchObject methods all have group 0 as their default argument. Later we'll see how to express groups that don't capture the span of text that they match.
组用 "(" 和 ")" 来指定,并且得到它们匹配文本的开始和结尾索引;这就可以通过一个参数用 group()、start()、end() 和 span() 来进行检索。组是从 0 开始计数的。组 0 总是存在;它就是整个 RE,所以 MatchObject 的方法都把组 0 作为它们缺省的参数。稍后我们将看到怎样表达不能得到它们所匹配文本的 span。

切换行号显示 切换行号显示 切换行号显示
   1 >>> p = re.compile('(a)b')
   2 >>> m = p.match('ab')
   3 >>> m.group()
   4 'ab'
   5 >>> m.group(0)
   6 'ab'

Subgroups are numbered from left to right, from 1 upward. Groups can be nested; to determine the number, just count the opening parenthesis characters, going from left to right.
小组是从左向右计数的,从1开始。组可以被嵌套。计数的数值可以能过从左到右计算打开的括号数来确定。

切换行号显示 切换行号显示 切换行号显示
   1 >>> p = re.compile('(a(b)c)d')
   2 >>> m = p.match('abcd')
   3 >>> m.group(0)
   4 'abcd'
   5 >>> m.group(1)
   6 'abc'
   7 >>> m.group(2)
   8 'b'

group() can be passed multiple group numbers at a time, in which case it will return a tuple containing the corresponding values for those groups.
group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。

切换行号显示 切换行号显示 切换行号显示
   1 >>> m.group(2,1,2)
   2 ('b', 'abc', 'b')

The groups() method returns a tuple containing the strings for all the subgroups, from 1 up to however many there are.

 

>>> m.groups()
('abc', 'b')

Backreferences in a pattern allow you to specify that the contents of an earlier capturing group must also be found at the current location in the string. For example, \1 will succeed if the exact contents of group 1 can be found at the current position, and fails otherwise. Remember that Python's string literals also use a backslash followed by numbers to allow including arbitrary characters in a string, so be sure to use a raw string when incorporating backreferences in a RE.

For example, the following RE detects doubled words in a string.

 

>>> p = re.compile(r'(\b\w+)\s+\1')
>>> p.search('Paris in the the spring').group()
'the the'

Backreferences like this aren't often useful for just searching through a string -- there are few text formats which repeat data in this way -- but you'll soon find out that they're very useful when performing string substitutions.

 

4.3 Non-capturing and Named Groups

Elaborate REs may use many groups, both to capture substrings of interest, and to group and structure the RE itself. In complex REs, it becomes difficult to keep track of the group numbers. There are two features which help with this problem. Both of them use a common syntax for regular expression extensions, so we'll look at that first.

Perl 5 added several additional features to standard regular expressions, and the Python re module supports most of them. It would have been difficult to choose new single-keystroke metacharacters or new special sequences beginning with "\" to represent the new features without making Perl's regular expressions confusingly different from standard REs. If you chose "&" as a new metacharacter, for example, old expressions would be assuming that "&" was a regular character and wouldn't have escaped it by writing \& or [&].

The solution chosen by the Perl developers was to use (?...) as the extension syntax. "?" immediately after a parenthesis was a syntax error because the "?" would have nothing to repeat, so this didn't introduce any compatibility problems. The characters immediately after the "?" indicate what extension is being used, so (?=foo) is one thing (a positive lookahead assertion) and (?:foo) is something else (a non-capturing group containing the subexpression foo).

Python adds an extension syntax to Perl's extension syntax. If the first character after the question mark is a "P", you know that it's an extension that's specific to Python. Currently there are two such extensions: (?P<name>...) defines a named group, and (?P=name) is a backreference to a named group. If future versions of Perl 5 add similar features using a different syntax, the re module will be changed to support the new syntax, while preserving the Python-specific syntax for compatibility's sake.

Now that we've looked at the general extension syntax, we can return to the features that simplify working with groups in complex REs. Since groups are numbered from left to right and a complex expression may use many groups, it can become difficult to keep track of the correct numbering, and modifying such a complex RE is annoying. Insert a new group near the beginning, and you change the numbers of everything that follows it.

First, sometimes you'll want to use a group to collect a part of a regular expression, but aren't interested in retrieving the group's contents. You can make this fact explicit by using a non-capturing group: (?:...), where you can put any other regular expression inside the parentheses.

 

>>> m = re.match("([abc])+", "abc")
>>> m.groups()
('c',)
>>> m = re.match("(?:[abc])+", "abc")
>>> m.groups()
()

Except for the fact that you can't retrieve the contents of what the group matched, a non-capturing group behaves exactly the same as a capturing group; you can put anything inside it, repeat it with a repetition metacharacter such as "*", and nest it within other groups (capturing or non-capturing). (?:...) is particularly useful when modifying an existing group, since you can add new groups without changing how all the other groups are numbered. It should be mentioned that there's no performance difference in searching between capturing and non-capturing groups; neither form is any faster than the other.

The second, and more significant, feature is named groups; instead of referring to them by numbers, groups can be referenced by a name.

The syntax for a named group is one of the Python-specific extensions: (?P<name>...). name is, obviously, the name of the group. Except for associating a name with a group, named groups also behave identically to capturing groups. The MatchObject methods that deal with capturing groups all accept either integers, to refer to groups by number, or a string containing the group name. Named groups are still given numbers, so you can retrieve information about a group in two ways:

 

>>> p = re.compile(r'(?P<word>\b\w+\b)')
>>> m = p.search( '(((( Lots of punctuation )))' )
>>> m.group('word')
'Lots'
>>> m.group(1)
'Lots'

Named groups are handy because they let you use easily-remembered names, instead of having to remember numbers. Here's an example RE from the imaplib module:

 

InternalDate = re.compile(r'INTERNALDATE "'
r'(?P<day>[ 123][0-9])-(?P<mon>[A-Z][a-z][a-z])-'
r'(?P<year>[0-9][0-9][0-9][0-9])'
r' (?P<hour>[0-9][0-9]):(?P<min>[0-9][0-9]):(?P<sec>[0-9][0-9])'
r' (?P<zonen>[-+])(?P<zoneh>[0-9][0-9])(?P<zonem>[0-9][0-9])'
r'"')

It's obviously much easier to retrieve m.group('zonem'), instead of having to remember to retrieve group 9.

Since the syntax for backreferences, in an expression like (...)\1, refers to the number of the group there's naturally a variant that uses the group name instead of the number. This is also a Python extension: (?P=name) indicates that the contents of the group called name should again be found at the current point. The regular expression for finding doubled words, (\b\w+)\s+\1 can also be written as (?P<word>\b\w+)\s+(?P=word):

 

>>> p = re.compile(r'(?P<word>\b\w+)\s+(?P=word)')
>>> p.search('Paris in the the spring').group()
'the the'

 

4.4 Lookahead Assertions

Another zero-width assertion is the lookahead assertion. Lookahead assertions are available in both positive and negative form, and look like this:

 

(?=...)
Positive lookahead assertion. This succeeds if the contained regular expression, represented here by ..., successfully matches at the current location, and fails otherwise. But, once the contained expression has been tried, the matching engine doesn't advance at all; the rest of the pattern is tried right where the assertion started.

 

(?!...)
Negative lookahead assertion. This is the opposite of the positive assertion; it succeeds if the contained expression doesn't match at the current position in the string.

An example will help make this concrete by demonstrating a case where a lookahead is useful. Consider a simple pattern to match a filename and split it apart into a base name and an extension, separated by a ".". For example, in "news.rc", "news"is the base name, and "rc" is the filename's extension.

The pattern to match this is quite simple:

.*[.].*$

Notice that the "." needs to be treated specially because it's a metacharacter; I've put it inside a character class. Also notice the trailing $; this is added to ensure that all the rest of the string must be included in the extension. This regular expression matches "foo.bar" and "autoexec.bat" and "sendmail.cf" and "printers.conf".

Now, consider complicating the problem a bit; what if you want to match filenames where the extension is not "bat"? Some incorrect attempts:

.*[.][^b].*$

The first attempt above tries to exclude "bat" by requiring that the first character of the extension is not a "b". This is wrong, because the pattern also doesn't match "foo.bar".

.*[.]([^b]..|.[^a].|..[^t])$

The expression gets messier when you try to patch up the first solution by requiring one of the following cases to match: the first character of the extension isn't "b"; the second character isn't "a"; or the third character isn't "t". This accepts "foo.bar" and rejects "autoexec.bat", but it requires a three-letter extension and won't accept a filename with a two-letter extension such as "sendmail.cf". We'll complicate the pattern again in an effort to fix it.

.*[.]([^b].?.?|.[^a]?.?|..?[^t]?)$

In the third attempt, the second and third letters are all made optional in order to allow matching extensions shorter than three characters, such as "sendmail.cf".

The pattern's getting really complicated now, which makes it hard to read and understand. Worse, if the problem changes and you want to exclude both "bat" and "exe" as extensions, the pattern would get even more complicated and confusing.

A negative lookahead cuts through all this:

.*[.](?!bat$).*$

The lookahead means: if the expression bat doesn't match at this point, try the rest of the pattern; if bat$ does match, the whole pattern will fail. The trailing $ is required to ensure that something like "sample.batch", where the extension only starts with "bat", will be allowed.

Excluding another filename extension is now easy; simply add it as an alternative inside the assertion. The following pattern excludes filenames that end in either "bat" or "exe":

.*[.](?!bat$|exe$).*$

 

5 Modifying Strings

Up to this point, we've simply performed searches against a static string. Regular expressions are also commonly used to modify a string in various ways, using the following RegexObject methods:

 

Method/Attribute  Purpose 
split() Split the string into a list, splitting it wherever the RE matches
sub() Find all substrings where the RE matches, and replace them with a different string
subn() Does the same thing as sub(), but returns the new string and the number of replacements

 

 

5.1 Splitting Strings

The split() method of a RegexObject splits a string apart wherever the RE matches, returning a list of the pieces. It's similar to the split() method of strings but provides much more generality in the delimiters that you can split by; split() only supports splitting by whitespace or by a fixed string. As you'd expect, there's a module-level re.split() function, too.

 

split( string [, maxsplit = 0])
Split string by the matches of the regular expression. If capturing parentheses are used in the RE, then their contents will also be returned as part of the resulting list. If maxsplit is nonzero, at most maxsplit splits are performed.

You can limit the number of splits made, by passing a value for maxsplit. When maxsplit is nonzero, at most maxsplit splits will be made, and the remainder of the string is returned as the final element of the list. In the following example, the delimiter is any sequence of non-alphanumeric characters.

 

>>> p = re.compile(r'\W+')
>>> p.split('This is a test, short and sweet, of split().')
['This', 'is', 'a', 'test', 'short', 'and', 'sweet', 'of', 'split', '']
>>> p.split('This is a test, short and sweet, of split().', 3)
['This', 'is', 'a', 'test, short and sweet, of split().']

Sometimes you're not only interested in what the text between delimiters is, but also need to know what the delimiter was. If capturing parentheses are used in the RE, then their values are also returned as part of the list. Compare the following calls:

 

>>> p = re.compile(r'\W+')
>>> p2 = re.compile(r'(\W+)')
>>> p.split('This... is a test.')
['This', 'is', 'a', 'test', '']
>>> p2.split('This... is a test.')
['This', '... ', 'is', ' ', 'a', ' ', 'test', '.', '']

The module-level function re.split() adds the RE to be used as the first argument, but is otherwise the same.

 

>>> re.split('[\W]+', 'Words, words, words.')
['Words', 'words', 'words', '']
>>> re.split('([\W]+)', 'Words, words, words.')
['Words', ', ', 'words', ', ', 'words', '.', '']
>>> re.split('[\W]+', 'Words, words, words.', 1)
['Words', 'words, words.']

 

5.2 Search and Replace

Another common task is to find all the matches for a pattern, and replace them with a different string. The sub() method takes a replacement value, which can be either a string or a function, and the string to be processed.

 

sub( replacement, string[, count = 0])
Returns the string obtained by replacing the leftmost non-overlapping occurrences of the RE in string by the replacement replacement. If the pattern isn't found, string is returned unchanged.

The optional argument count is the maximum number of pattern occurrences to be replaced; count must be a non-negative integer. The default value of 0 means to replace all occurrences.

Here's a simple example of using the sub() method. It replaces colour names with the word "colour":

 

>>> p = re.compile( '(blue|white|red)')
>>> p.sub( 'colour', 'blue socks and red shoes')
'colour socks and colour shoes'
>>> p.sub( 'colour', 'blue socks and red shoes', count=1)
'colour socks and red shoes'

The subn() method does the same work, but returns a 2-tuple containing the new string value and the number of replacements that were performed:

 

>>> p = re.compile( '(blue|white|red)')
>>> p.subn( 'colour', 'blue socks and red shoes')
('colour socks and colour shoes', 2)
>>> p.subn( 'colour', 'no colours at all')
('no colours at all', 0)

Empty matches are replaced only when they're not adjacent to a previous match.

 

>>> p = re.compile('x*')
>>> p.sub('-', 'abxd')
'-a-b-d-'

If replacement is a string, any backslash escapes in it are processed. That is, "\n" is converted to a single newline character, "\r" is converted to a carriage return, and so forth. Unknown escapes such as "\j" are left alone. Backreferences, such as "\6", are replaced with the substring matched by the corresponding group in the RE. This lets you incorporate portions of the original text in the resulting replacement string.

This example matches the word "section" followed by a string enclosed in "{", "}", and changes "section" to "subsection":

 

>>> p = re.compile('section{ ( [^}]* ) }', re.VERBOSE)
>>> p.sub(r'subsection{\1}','section{First} section{second}')
'subsection{First} subsection{second}'

There's also a syntax for referring to named groups as defined by the (?P<name>...) syntax. "\g<name>" will use the substring matched by the group named "name", and "\g<number>" uses the corresponding group number. "\g<2>" is therefore equivalent to "\2", but isn't ambiguous in a replacement string such as "\g<2>0". ("\20" would be interpreted as a reference to group 20, not a reference to group 2 followed by the literal character "0".) The following substitutions are all equivalent, but use all three variations of the replacement string.

 

>>> p = re.compile('section{ (?P<name> [^}]* ) }', re.VERBOSE)
>>> p.sub(r'subsection{\1}','section{First}')
'subsection{First}'
>>> p.sub(r'subsection{\g<1>}','section{First}')
'subsection{First}'
>>> p.sub(r'subsection{\g<name>}','section{First}')
'subsection{First}'

replacement can also be a function, which gives you even more control. If replacement is a function, the function is called for every non-overlapping occurrence of pattern. On each call, the function is passed a MatchObject argument for the match and can use this information to compute the desired replacement string and return it.

In the following example, the replacement function translates decimals into hexadecimal:

 

>>> def hexrepl( match ):
...     "Return the hex string for a decimal number"
...     value = int( match.group() )
...     return hex(value)
...
>>> p = re.compile(r'\d+')
>>> p.sub(hexrepl, 'Call 65490 for printing, 49152 for user code.')
'Call 0xffd2 for printing, 0xc000 for user code.'

When using the module-level re.sub() function, the pattern is passed as the first argument. The pattern may be a string or a RegexObject; if you need to specify regular expression flags, you must either use a RegexObject as the first parameter, or use embedded modifiers in the pattern, e.g. sub("(?i)b+", "x", "bbbb BBBB") returns 'x x'.

 

6 Common Problems

Regular expressions are a powerful tool for some applications, but in some ways their behaviour isn't intuitive and at times they don't behave the way you may expect them to. This section will point out some of the most common pitfalls.

 

6.1 Use String Methods

Sometimes using the re module is a mistake. If you're matching a fixed string, or a single character class, and you're not using any re features such as the IGNORECASE flag, then the full power of regular expressions may not be required. Strings have several methods for performing operations with fixed strings and they're usually much faster, because the implementation is a single small C loop that's been optimized for the purpose, instead of the large, more generalized regular expression engine.

One example might be replacing a single fixed string with another one; for example, you might replace "word"with "deed". re.sub() seems like the function to use for this, but consider the replace() method. Note that replace() will also replace "word" inside words, turning "swordfish" into "sdeedfish", but the naïve RE word would have done that, too. (To avoid performing the substitution on parts of words, the pattern would have to be \bword\b, in order to require that "word" have a word boundary on either side. This takes the job beyond replace's abilities.)

Another common task is deleting every occurrence of a single character from a string or replacing it with another single character. You might do this with something like re.sub('\n', ' ', S), but translate() is capable of doing both tasks and will be faster that any regular expression operation can be.

In short, before turning to the re module, consider whether your problem can be solved with a faster and simpler string method.

 

6.2 match() versus search()

The match() function only checks if the RE matches at the beginning of the string while search() will scan forward through the string for a match. It's important to keep this distinction in mind. Remember, match() will only report a successful match which will start at 0; if the match wouldn't start at zero, match() will not report it.

 

>>> print re.match('super', 'superstition').span()
(0, 5)
>>> print re.match('super', 'insuperable')
None

On the other hand, search() will scan forward through the string, reporting the first match it finds.

 

>>> print re.search('super', 'superstition').span()
(0, 5)
>>> print re.search('super', 'insuperable').span()
(2, 7)

Sometimes you'll be tempted to keep using re.match(), and just add .* to the front of your RE. Resist this temptation and use re.search() instead. The regular expression compiler does some analysis of REs in order to speed up the process of looking for a match. One such analysis figures out what the first character of a match must be; for example, a pattern starting with Crow must match starting with a "C". The analysis lets the engine quickly scan through the string looking for the starting character, only trying the full match if a "C" is found.

Adding .* defeats this optimization, requiring scanning to the end of the string and then backtracking to find a match for the rest of the RE. Use re.search() instead.

 

6.3 Greedy versus Non-Greedy

When repeating a regular expression, as in a*, the resulting action is to consume as much of the pattern as possible. This fact often bites you when you're trying to match a pair of balanced delimiters, such as the angle brackets surrounding an HTML tag. The naïve pattern for matching a single HTML tag doesn't work because of the greedy nature of .*.

 

>>> s = '<html><head><title>Title</title>'
>>> len(s)
32
>>> print re.match('<.*>', s).span()
(0, 32)
>>> print re.match('<.*>', s).group()
<html><head><title>Title</title>

The RE matches the "<" in "<html>", and the .* consumes the rest of the string. There's still more left in the RE, though, and the > can't match at the end of the string, so the regular expression engine has to backtrack character by character until it finds a match for the >. The final match extends from the "<" in "<html>"to the ">" in "</title>", which isn't what you want.

In this case, the solution is to use the non-greedy qualifiers *?, +?, ??, or {m,n}?, which match as little text as possible. In the above example, the ">" is tried immediately after the first "<" matches, and when it fails, the engine advances a character at a time, retrying the ">" at every step. This produces just the right result:

 

>>> print re.match('<.*?>', s).group()
<html>

(Note that parsing HTML or XML with regular expressions is painful. Quick-and-dirty patterns will handle common cases, but HTML and XML have special cases that will break the obvious regular expression; by the time you've written a regular expression that handles all of the possible cases, the patterns will be very complicated. Use an HTML or XML parser module for such tasks.)

 

6.4 Not Using re.VERBOSE

By now you've probably noticed that regular expressions are a very compact notation, but they're not terribly readable. REs of moderate complexity can become lengthy collections of backslashes, parentheses, and metacharacters, making them difficult to read and understand.

For such REs, specifying the re.VERBOSE flag when compiling the regular expression can be helpful, because it allows you to format the regular expression more clearly.

The re.VERBOSE flag has several effects. Whitespace in the regular expression that isn't inside a character class is ignored. This means that an expression such as dog | cat is equivalent to the less readable dog|cat, but [a b] will still match the characters "a", "b", or a space. In addition, you can also put comments inside a RE; comments extend from a "#" character to the next newline. When used with triple-quoted strings, this enables REs to be formatted more neatly:

 

pat = re.compile(r"""
\s*                 # Skip leading whitespace
(?P<header>[^:]+)   # Header name
\s* :               # Whitespace, and a colon
(?P<value>.*?)      # The header's value -- *? used to
# lose the following trailing whitespace
\s*$                # Trailing whitespace to end-of-line
""", re.VERBOSE)

This is far more readable than:

 

pat = re.compile(r"\s*(?P<header>[^:]+)\s*:(?P<value>.*?)\s*$")

 

7 Feedback

Regular expressions are a complicated topic. Did this document help you understand them? Were there parts that were unclear, or Problems you encountered that weren't covered here? If so, please send suggestions for improvements to the author.

The most complete book on regular expressions is almost certainly Jeffrey Friedl's Mastering Regular Expressions, published by O'Reilly. Unfortunately, it exclusively concentrates on Perl and Java's flavours of regular expressions, and doesn't contain any Python material at all, so it won't be useful as a reference for programming in Python. (The first edition covered Python's now-obsolete regex module, which won't help you much.) Consider checking it out from your library.

 

About this document ...

Regular Expression HOWTO

This document was generated using the LaTeX2HTML translator.

LaTeX2HTML is Copyright © 1993, 1994, 1995, 1996, 1997, Nikos Drakos, Computer Based Learning Unit, University of Leeds, and Copyright © 1997, 1998, Ross Moore, Mathematics Department, Macquarie University, Sydney.

The application of LaTeX2HTML to the Python documentation has been heavily tailored by Fred L. Drake, Jr. Original navigation icons were contributed by Christopher Petrilli.


 Posted by at 11:44 上午
11月 132010
 

主成分分析
1简介
  在用统计分析方法研究这个多变量的课题时,变量个数太多就会增加课题的复杂性。人们自然希望变量个数

较少而得到的信息较多。在很多情形,变量之间是有一定的相关关系的,当两个变量之间有一定相关关系时,可

以解释为这两个变量反映此课题的信息有一定的重叠。主成分分析是对于原先提出的所有变量,建立尽可能少的

新变量,使得这些新变量是两两不相关的,而且这些新变量在反映课题的信息方面尽可能保持原有的信息。
2原理
  设法将原来变量重新组合成一组新的互相无关的几个综合变量,同时根据实际需要从中可以取出几个较少的

综合变量尽可能多地反映原来变量的信息的统计方法叫做主成分分析或称主分量分析,也是数学上处理降维的一

种方法。
3步骤
主成分分析主要步骤如下:   
1.指标数据标准化;   
2.指标之间的相关性判定;  
3.计算特征值与特征向量
4.计算主成分贡献率及累计贡献率
5.计算主成分载荷

 

python实现
#-*- coding:utf-8 -*-
from pylab import *
from numpy import *

def pca(data,nRedDim=0,normalise=1):
   
    # 数据标准化
    m = mean(data,axis=0)
    data -= m

    # 协方差矩阵
    C = cov(transpose(data))

    # 计算特征值特征向量,按降序排序
    evals,evecs = linalg.eig(C)
    indices = argsort(evals)
    indices = indices[::-1]
    evecs = evecs[:,indices]
    evals = evals[indices]

    if nRedDim>0:
        evecs = evecs[:,:nRedDim]
   
    if normalise:
        for i in range(shape(evecs)[1]):
            evecs[:,i] / linalg.norm(evecs[:,i]) * sqrt(evals[i])

    # 产生新的数据矩阵
    x = dot(transpose(evecs),transpose(data))
    # 重新计算原数据
    y=transpose(dot(evecs,x))+m
    return x,y,evals,evecs

#-*- coding:utf-8 -*-
from pylab import *
from numpy import *

import pca
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus'] = False
x = random.normal(5,.5,1000)
y = random.normal(3,1,1000)
a = x*cos(pi/4) + y*sin(pi/4)
b = -x*sin(pi/4) + y*cos(pi/4)

plot(a,b,'.')
xlabel('x')
ylabel('y')
title('原数据集')
data = zeros((1000,2))
data[:,0] = a
data[:,1] = b

x,y,evals,evecs = pca.pca(data,1)
print y
figure()
plot(y[:,0],y[:,1],'.')
xlabel('x')
ylabel('y')
title('重新构造数据')
show()





 Posted by at 8:26 下午
11月 112010
 

 为什么用python?
1在人工智能和web应用方面非常流行
2容易学习
3容易实现,相对于c++,java更加精简
4容易阅读和维护

python是一种脚本语言,尤其在文本处理方面具有很强的优势
python是一种高级语言,类似于人的思维
python是过程化的,同时也是面向对象的

"hello world"
c版本
#include <stdio.h>
int main(int argc, char ** argv)
{
 printf(“Hello, World!\n”);
}
java版本
public class Hello
{
 public static void main(String argv[])
 {
 System.out.println(“Hello, World!”);
 }
}
python版本
print “Hello, World!”

python解释器
运行python程序的三种方式:
1交互式
Python 2.6.5 (r265:79096, Mar 19 2010, 21:48:26) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.

    ****************************************************************
    Personal firewall software may warn about the connection IDLE
    makes to its subprocess using this computer's internal loopback
    interface.  This connection is not visible on any external
    interface and no data is sent to or received from the Internet.
    ****************************************************************
   
IDLE 2.6.2     
>>> print 'hello, world'
hello, world
>>>
2命令行
python foo.py
3添加默认的解释器
#!/usr/bin/python
使程序可执行 chmod +x foo.py
./foo.py

python基础
1基本python语法
python程序可以通过任何文本编辑器来处理,并且以.py作为扩展名。python程序不一定需要第一行或者最后一

行,但是可以给出python环境路径作为第一行:#!/usr/bin/python,并且可以可执行。另外,python程序可以从

命令提示符运行,python file.py。在python中,没有花括号或者分号。它是一种高级程序设计语言。它通过块

功能来标识代码段的缩进。
#!/usr/bin/python
if (x > y):
   print("x is greater than y")
   x = x -1
else:
   print("x is less than or equal to y")
2变量和数据类型
python变量命名以字母或者下划线开头,并且变量名是大小写敏感的。变量不需要声明,数据类型可以从赋值语

句中推断出来。python支持的数据类型:
boolean,integer,long,float,string,list,object,None
例如:
bool = True
name = "Craig"
age = 26
pi = 3.14159
print(name + ' is ' + str(age) + ' years old.')
-> Craig is 26 years old.
变量范围:python中的大多数变量在它们自己的函数或者类中是局部变量。
全局变量:可以通过global关键字定义。
a = 1
b = 2
def Sum():
   global a, b
   b = a + b
Sum()
print(b)
-> 3

3语句和表达式
常用的python语句:
print
赋值语句
输入语句
raw_input:允许用户输入字符串,如果是需要数值型,可以使用int或者float函数将string转化为相应的类型
import:导入模块到python中
print "Hello World"
print('Print works with or without parenthesis')
print("and single or double quotes")
print("Newlines can be escaped like\nthis.")
print("This text will be printed"),
print("on one line becaue of the comma.")
name = raw_input("Enter your name: ")
a = int(raw_input("Enter a number: "))
print(name + "'s number is " + str(a))
a = b = 5
a = a + 4
print a,b
9 5
python表达式包括:
a = b = 5 #赋值表达式
b += 1 #复合赋值表达式
c = "test"
import os,math #导入os和math模块中的所有函数

4操作符和数学运算
操作符:
算术+, -, *, /, %
比较 ==, !=, <, >, <=, >=
逻辑and, or, not
乘方**
系统调用os.system('ls -l')  需要导入os模块
数学运算:
绝对值: a = abs(-7.5)
反正玄函数: x = asin(0.5) #returns in rads
向上近似计算: print(ceil(4.2))
余弦: a = cos(x) #x in rads
计算角度: a = degrees(asin(0.5)) #a=30
e: y = exp(x) #y=e^x
向下近似计算: a = floor(a+0.5)
自然对数: x = log(y); #Natural Log
   x = log(y,5); #Base-5 log
以10为底的对数: x = log10(y)
最大值: mx = max(1, 7, 3, 4) #7
   mx = max(arr) #max value in array
最小值: mn = min(3, 0, -1, x) #min value
乘方: x = pow(y,3) #x=y^3
弧度: a = cos(radians(60)) #a=0.5
随机数 #: Random number functions require import random
   random.seed() #Set the seed based on the system time.
   x = random() #Random number in the range [0.0, 1.0)
   y = randint(a,b) #Random integer in the range [a, b]

近似: print round(3.793,1; #3.8 - rounded to 1 decimal
   a = round(3.793,0) #a=4.0
sin: a = sin(1.57) #in rads
平方根: x = sqrt(10) #3.16...
5字符串
字符串是被单引号或者双引号定义。如果在字符串前加上r,那么可以不考虑特殊字符转换。
 print 'I\'ll be back.'.
print r'The newline \n will not expand'
a = "Gators"
print "The value of a is \t" + a
-> The value of a is       Gators

如果没有使用原字符r处理,则需要使用转义字符\n, \r, \t, \\ 和 \" 等等。另外, """可以使字符串跨多行

表示。
print """
This is an example of a string in the heredoc syntax.
This text can span multiple lines
"""
字符串运算符:==, !=, <, >, <=和 >=
s = str(3.5)
name = "Lee"
print name + "'s number is " + str(24)
字符串函数:
s = "Go Gators! Come on Gators!"
子串抽取:x = s[3:9] #x = "Gators"
  x = s[:2] #x = "Go"
  x = s[19:] #x = "Gators!"
  x = s[-7:-2] #x = "Gator"
子串计算;x = s.count("Gator") #x = 2
判断是否以某字符串结束: x = s.endswith("Gators") #x = False
查找:x = s.find("Gator") #x = 3
  x = s.find("gator") #x = -1
连接: a = ['abc','def','ghi']
  t = "--"
  x = t.join(a) #x = abc--def--ghi
长度:x = len(s) #x = 26
小写:print s.lower() #go gators! come on gators!
替换:x = s.replace("Gators","Tigers",1) #x = Go Tigers! Come on Gators!
从右边开始寻找:x = s.rfind("Gator") #x = 19
拆分:a = s.split() #a=['Go', 'Gators!', 'Come', 'on', 'Gators!']
判断是否以某字符串开始:x = s.startswith("Go") #x = True
去除头尾字符,默认空格:strip([chars])
转换为大写:upper()
6数组
Arrays in basic Python are actually lists that can contain mixed datatypes. However, the numarray

module contains support for true arrays, including multi-dimensional arrays, as well as IDL-style

array operations and the where function. To use arrays, you must import numarray or from numarray

import *. Unfortunately, numarray generally only suports numeric arrays. Lists must be used for

strings or objects. By importing numarray.strings and numarray.objects, you can convert string and

object lists to arrays and use some of the numarray features, but only numeric lists are fully

supported by numarray.
Creating lists: A list can be created by defining it with []. A numbered list can also be created

with the range function which takes start and stop values and an increment.
list = [2, 4, 7, 9]
list2 = [3, "test", True, 7.4]
a = range(5) #a = [0,1,2,3,4]
a = range(10,0,-2) #a = [10,8,6,4,2]
An empty list can be initialized with [] and then the append command can be used to append data to

the end of the list:
a=[]
a.append("test")
a.append(5)
print a
-> ['test', 5]
Finally, if you want a list to have a predetermined size, you can create a list and fill it with

None's:
a=[None]*length
a[5] = "Fifth"
a[3] = 6
print len(a)
-> 10
print a
-> [None, None, None, 6, None, 'Fifth', None, None, None, None]

Removing from lists: The pop method can be used to remove any item from the list:
a.pop(5)
print a
-> [None, None, None, 6, None, None, None, None, None]

Creating arrays: An array can be defined by one of four procedures: zeros, ones, arange, or array.

zeros creates an array of a specified size containing all zeros:
a = zeros(5) #a=[0 0 0 0 0]
ones similarly creates an array of a certain size containing all ones:
a = ones(5) #a=[1 1 1 1 1]
arange works exactly the same as range, but produces an array instead of a list:
a = arange(10,0,-2) #a = [10 8 6 4 2] And finally, array can be used to convert a list to an

array. For instance, when reading from a file, you can create an empty list and take advantage of

the append command and lists not having a fixed size. Then once the data is all in the list, you

can convert it to an array:
a = [1, 3, 9] #create a list and append it
a.append(3)
a.append(5)
print a
-> [1, 3, 9, 3, 5]
a = array(a)
print a
-> [1 3 9 3 5]

Multi-dimensional lists: Because Python arrays are actually lists, you are allowed to have jagged

arrays. Multi-dimensional lists are just lists of lists:
a=[[0,1,2],[3,4,5]]
print a[1]
-> [3, 4, 5]
s = ["Lee", "Walsh", "Roberson"]
s2 = ["Williams", "Redick", "Ewing", "Dockery"]
s3 = [s, s2]
print s3[1][2]
-> Ewing

Multi-dimensional arrays: However, numarray does support true multi-dimensinoal arrays. These can

be created through one of five methods: zeros, ones, array, arange, and reshape. zeros and ones

work the same way as single dimensions except that they take a tuple of dimensions (a comma

separated list enclosed in parentheses) instead of a single argument:
a = zeros((3,5))
a[1,2] = 8
print a
-> [[0 0 0 0 0]
    [0 0 8 0 0]
    [0 0 0 0 0]]
b = ones((2,3,4)) #create a 2x3x4 array containing all ones.

array works the same way as for 1-d arrays: you can create a list and then convert it to an array.

Note with multi-dimensional arrays though, trying to use array to convered a jagged list into an

array will cause an error. Lists must be rectangular to be able to be converted to arrays.
s = ["Lee", "Walsh", "Roberson", "Brewer"]
s2 = ["Williams", "Redick", "Ewing", "Dockery"]
s3 = [s, s2]
s4 = array(s3)
print s4 + "test"
-> [['Leetest', 'Walshtest', 'Robersontest', 'Brewertest'],
    ['Williamstest', 'Redicktest', 'Ewingtest', 'Dockerytest']]
print s4[:,1:3]
-> [['Walsh', 'Roberson'],
    ['Redick', 'Ewing']]
arange also works the same as with 1-d arrays except you need to pass the shape parameter:
a = arange(25, shape=(5,5)),br> And finally, reshape can be used to convert a 1-d array into a

multi-dimensional array. To create a 5x5 array with the elements numbered from 0 to 24, you could

use:
b = arange(25)
b = reshape(b,5,5)

Array Dimensions and Subscripts: When creating a multi-dimensional array, the format is ([[depth,]

height,] width). Therefore, when accessing array elements in a two dimensional array, the row is

listed first, then the column. When accessing an element of a two-dimensional list, the following

notation must be used: list[i][j]. However, two dimensional arrays can also use the notation:

array[i,j]. In fact, this is the preferred notation of the two for arrays because you cannot use

wildcards in the first dimension of the array[i][j] notation (i.e., array[1:3][4] would cause an

error whereas array[1:3,4] is valid).

Wildcards can be used in array subscripts using the : , which is known as slicing. This is similar

to IDL, with one major difference: if a=[0 1 2 3 4 5], in IDL a[1:4] = [1 2 3 4], but in Python,

a[1:4] = [1 2 3]. In Python, when slicing array[i:j], it returns an array containing elements from

i to j-1. Just like with strings, indices of arrays can be negative, in which case they count from

the right instead of the left, i.e. a[-4:-1] = [2 3 4]. A : can also specify the rest of the

elements or up to element, or all elements and arrays or lists can be used to subscript other

arrays:
print a[:3] #[0 1 2]
print a[4:] #[4 5]
print a[:] #[0 1 2 3 4 5]
print a[[1,3,4]] #[1 3 4]
Note that slicing in python does not create a new array but just a pointer to the original array.

b=a[0:10] followed by b[0] = 5 also changes a[0] to 5. To avoid this, use b = copy(a[0:10])
Array Operators:
Concatenation:

Lists: a + b
For Lists, the + operator appends the list on the right (b) to the list on the left.
a = ["Roberson", "Walsh"]
b = ["Lee", "Humphrey"]
-> a+b = ["Roberson", "Walsh", "Lee", "Humphrey"]

Arrays: concatenate((a,b)[,axis])
For arrays, use the numarry function concatenate. It also allows you to specify the axis when

concatenating multi-dimensional arrays.
b = arange(5)
print concatenate((b, arange(6)))
-> [0 1 2 3 4 0 1 2 3 4 5]
b=reshape(b,5,1)
print concatenate((b,a),axis=1)
-> [[0 0 0 0]
    [1 0 0 0]
    [2 0 8 0]
    [3 0 0 0]
    [4 0 0 0]]

Equality: a == b and Inequality: a != b
For lists, these work the same as for scalars, meaning they can be used in if statments. For

arrays, they return an array containing true or false for each array element.
 
Array Functions: All functions but len are for arrays only
len: returns the length of a list/array.
   s = ["Lee", "Walsh", "Roberson", "Brewer"]
   print len(s) #4

argmax([axis]): returns the index of the largest element in a 1D array or an array of the largest

indices along the specified axis for a multi-dimensional array.
   a = array([[1,6,9], [2,4,0], [7,4,8]])
   print a.argmax(1)
  -> [2 1 2]

argmin([axis]): returns the index of the smallest element in a 1D array or an array of the

smallest ndices along the specified axis for a multi-dimensional array.
   b = array([2,4,7,1,3,-1,5])
   print b.argmin()
  -> 5

argsort([axis]): returns an array of indices that allow access to the elements of the array in

ascending order.
   print b.argsort()
  -> [5 3 0 4 1 6 2]
   print b[b.argsort()]
  -> [-1 1 2 3 4 5 7]
   print a.argsort(1)
  -> [[0 1 2]
      [2 0 1]
      [1 0 2]]

astype(type): returns a copy of the array converted to the specified type.
   a = a.astype('Float64')
   b = b.astype('Int32')

copy(): returns a copy of the array.
   c = a[:,2].copy()
   print c
  -> [9 0 8]

diagonal(): for multi-dimensional arrays, returns the diagonal elements of the array, where the

row and column indices are equal.
   print a.diagonal()
  -> [1 4 8]

info(): prints informations about the array which may be useful for debugging.

max(): returns the largest element in the array
   print a.max()
  -> 9

mean(): returns the average of all elements in an array
   print a.mean()
  -> 4.55555555556

min(): returns the smallest element in the array
   print b.min()
  -> -1

nelements(): returns the total number of elements in the array
   print a.nelements()
  -> 9

product(array [,axis]): returns the product of an array or an array of the products along an axis

of an array.
   print product(b)
  -> -840
   print product(a,1)
  -> [ 54 0 224]

reshape(array, shape): function that changes the shape of an array. But the new shape must have

the same size as the old shape, otherwise an error will occur.
   c = reshape(a, 9)
   a = reshape(c,(3,3))

resize(shape): shrinks/grows the array to a new shape. Can be called as a method (replaces old

array) or a function. The new shape does not have to be the same size as the old shape. If it is

smaller, values will be cut off, and it if is bigger, values will repeat.
   a.resize(5)
   print a
  -> [1 6 9 2 4]
   a.resize(2,6)
   print a
  -> [[1 6 9 2 4 0]
      [7 4 8 1 6 9]]
   c = resize(a,(2,2))
   print c
  -> [[1 6]
      [9 2]]

shape(array): returns the dimensions of the array in a tuple
   print shape(a), shape(b), shape(a)[0]*shape(a)[1]
  -> (3,3)    (7,)    9

sort(array [,axis]): returns an array containing a copy of the data in the array and the elements

sorted in increasing order. In the case of a multi-dimensional array, the data will be sorted

along one axis and not across the whole array.
   print sort(b)
  -> [-1 1 2 3 4 5 7]
   print sort(a)
  -> [[1 6 9]
      [0 2 4]
      [4 7 8]]
   print sort(a,0)
  -> [[1 4 0]
      [2 4 8]
      [7 6 9]]

stddev(): returns the std deviation of all elements in the array
   print a.stddev()
  -> 3.16666666667

sum(): Can be called as a method or a function. The behavior is identical for 1-d arrays. But for

multi-dimensional arrays, calling as a method returns the sum of the entire array, whereas calling

it as a function allows you to specify an axis and returns an array with the sums along that axis.
   print a.sum()
  -> 41
   print sum(a)
  -> [10 14 17]
   print sum(a,1)
  -> [16 6 19]

trace(): Returns the sum of the diagonal elements of an array
   print a.trace()
  -> 13

type(): returns a string containing the type of the array.
   print a.type()
  -> Int32

tolist(): returns a list containing the same data as the array.
   c = a.tolist()

transpose(): Can be called as a method (replaces old array) or a function. Returns the transpose

of the array.
   a.transpose()
   b = transpose(a)

where(expr, 1, 0): Similar to the IDL where function. Returns an array of the same size and

dimensions containing 1 if the condition is true and 0 if the condition is false. Any value may be

substituted for 1 and 0, but they are the recommended values (i.e. true, false) so that compress

can be used to extract values from the array: compress(mask_array, data_array).
   c = where(b > 2, 1, 0)
   print c
  -> [0 1 1 0 1 0 1]
   print compress(c,b)
  -> [4 7 3 5]
   c = where(a > 2, 1, 0)
   print c
  -> [[0 1 1]
      [0 1 0]
      [1 1 1]]
   print compress(c,a)
  -> [6 9 4 7 4 8]

 7条件语句
if
if-else
if-elseif
if a > b: print "a is greater than b";

if (a > b):
   print "a is greater than b"
   print "blocks are defined by indentation"
elif (a < b):
   print "a is less than b"
else:
   print "a is equal to b"
8循环语句
for,while,continue,break,else,foreach
for j in range(10): print "Value number " + str(j) +" is "+value[j]

for j in range(10,0,-2):
   x = x + j
   print x

while (b < a):
   print "b is less than a."
   b=b+1

for j in range(0,10):
   while(k < j):
     print "j = " + str(j) + " k = "+str(k)
     if (j == 1): break
     k=k+1
   print "j equals k or j equals 1"

a = ["abc","def","ghi"]
for x in a:
   print x

9函数
函数定义:
def funct(arg_11, arg_2, ..., arg_n):
   print "This is a function."
   return value
参数:函数参数是通过值传递,因此如果在函数内改变参数的值,在函数外面值还是不会变的。如果需要修改非

局部变量,必须在函数的第一行定义变量为global的。如果声明某个变量为全局,那么他就不能在变量列表中使

用。例如下面的会报错:
function double(x):
   global x
   x = x*2
   return
double(x)
修改如下:
function double(n):
   n = n * 2
   return n
x = double(x)
或者
function doubleX():
   global x
   x = x * 2
   return
doubleX()
默认参数:
def square(x = 5):
   return x*x
变长参数列表:
def var_args(arg1, arg2, *args):
关键字参数:
def player(name, number, team="Florida"):
   print(name + "wears number " + str(number) + "for " + team)
player("Matt Walsh", 44)
player(number = 44, name = "David Lee")
player("Anthony Roberson", number = 1)
player(name = "J.J. Redick", number = 4, team = "Duke")
返回值:
return var
不能返回多值,但是可以通过返回数组或者对象
函数变量:
def test():
   print 'This is a test.'
var = test
var() #this calles test()
var = circle.setRadius
var(3) #this calls circle.setRadius(3)

10类和面向对象
初始化变量
封装:python并不是真的支持封装,因为它不支持通过私有成员和保护成员进行数据隐藏。但是,存在一些伪封

装实现。如果标识符以两个下划线开头__a,那么只能是类内部访问self.__a,但是在类外部,可以通过

instance._classname__a访问。
继承
抽象类
父类
构造函数
比较对象
class Rectangle:
#Optionally define variable width
   width = 0
#Constructor with default arguments
   def __init__(self, width = 0, height = 0):
     self.width = width
     self.height = height
#functions
   def setWidth(self, width):
     self.width = width
   def setHeight(self, height):
     self.height = height
   def getArea(self):
     return self.width * self.height

arect = Rectangle() #create a new Rectangle with dimensions 0x0.
arect.setWidth(4)
arect.setHeight(6)
print arect.getArea()
  -> 24
rect2 = Rectangle(7,3) #new Rectangle with dimensions 7x3.

Extended Class:
class RectWithPerimeter(Rectangle):
#add new functions
   def getPerimeter(self):
     return 2*self.height + 2*self.width
   def setDims(self, width, height):
#call base class methods from Rectangle
     Rectangle.setWidth(self, width)
     Rectangle.setHeight(self, height)
arect = RectWithPerimeter(6,5) #Uses the constructor from Rectangle because no new constructor is

provided to override it.
print arect.getArea() #Uses the getArea function from Rectangle and prints 30.
print arect.getPerimeter() #Uses getPerimeter from RectWithPerimeter and prints 22.
arect.setDims(4,9) #Use setDims to change the dimensions.

11文件操作
打开文件:file open(string filename, string mode)
'r': Open for reading.
'w': Open for writing. Any existing data will be overwritten.
'a': Open for writing. New data will be appended to existing data.
'b': Use this flag when working with binary files (e.g. 'rb').
检查文件:bool os.access(string path, int mode)
os.F_OK: test the existence of path
os.R_OK: tests if path exists and is readable
os.W_OK: tests if path exists and is writable
os.X_OK: tests if path exists and is executable
文件操作:bool os.system(string command)
bool chmod(string path, int mode)
list listdir(string path)
bool mkdir(string pathname [, int mode])
bool remove(String filename)
bool rename(string oldname, string newname)
bool symlink(string target, string link)
读取文件:
string read([int length])
string readline([int length])
list readlines([int sizehint])
EOF:
while (s != ""):
   s = f.readline()
   do_something
写文件:
void write(string string)
void writelines(list data)
并发
序列化对象:
f = open("file.dat","wb")
pickle.dump(x,f)
f.close()
反序列化f = open("file.dat","rb")
y = pickle.load(f)
f.close()
端口:
服务器
import socket
mySocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mySocket.bind(('', 2727))
mySocket.listen(1)
conn, addr = mySocket.accept()
print 'Connected with ', addr
while True:
   data = conn.recv(1024)
   if not data: break
   print data
   conn.send("Data received")
conn.close()
客户端
cSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
cSocket.connect(("polaris.astro.ufl.edu","2727"))
cSocket.send("Hello world!")
data = cSocket.recv(1024)
cSocket.close()
print data

file = open("data/teams.txt","rb")
team = "nonempty"
while (team != ""):
   team = file.readline()
   if (team != ""): print team[:-1]   #get rid of extra newline character
file.close()

file = open("data/teams.txt","rb")
team = file.readlines()
file.close()

list = ["Florida","Clemson","Duke"]
file = open("data/teams.txt","wb")
for j in list: file.write(j+"\n")
file.close()

import pickle, fcntl
player = Player("J.J. Redick", "Duke", 4)
file = open("data/players.txt", "a")
fcntl.flock(file.fileno(), fcntl.LOCK_EX)
pickle.dump(player, file)
fcntl.flock(file.fileno(), fcntl.LOCK_UN)
file.close()

12python图像处理
python通过pyfits模块支持FITS文件
HDUList open(string): 打开文件
info(): 打印文件中的对象信息
x = pyfits.open("NGC3031.fits")
x.info()

-> Filename: NGC3031.fits
No.  Name     Type    Cards Dimensions Format
0  PRIMARY PrimaryHDU    6  (530, 530)  UInt8
print x[0].header.ascardlist()

-> SIMPLE  =                    T
BITPIX  =                    8
NAXIS   =                    2
NAXIS1  =                  530
NAXIS2  =                  530
HISTORY Written by XV 3.10a
print x[0].header['NAXIS1']
-> 530
print x[0].header[3]
-> 530

print x[0].data[3,0:5]
-> [11 11 11 9 9]

x[0].data[3,0:3] = array([0,0,0])
print x[0].data[3,0:5]
-> [0 0 0 9 9]

x[0].data += 5 #using numarray to operate on entire array
print x[0].data[3,0:5]
-> [ 5 5 5 14 14]

x.writeto("new_file.fits")
x.close()
13猜数字
#!/usr/bin/python
import random, math
random.seed()
x = math.floor(random.random()*100)+1
z = 0
b = 0
while x != z:
   b=b+1
   z = input("Guess My Number: ")
   if z < x: print("Higher!")
   if z > x: print("Lower!")
print("Correct! " + str(b) + " tries.")

 

 

 

 

 

 

 

 

 


 

 Posted by at 3:49 下午
4月 212010
 
##################################################
# A DEMO HOW TO COPY A SQLITE DB TABLE FROM DISK #
# INTO MEMORY                                    #
##################################################

import sqlite3

# CONNECT TO THE IN-MEMORY DATABASE
con = sqlite3.connect(":memory:")
cur = con.cursor()

# ATTACH SQLITE DB IN THE DISK
cur.execute("attach 'd:\mydb' as filedb")

# COPY THE TABLE INTO IN-MEMORY DB
cur.execute("create table memory_tbl as select * from filedb.mytab")

# RELEASE THE DB IN THE DISK
cur.execute("detach filedb")

# FETCH ROWS FROM IN-MEMORY DB
cur.execute("select Sepal_Length, Species from memory_tbl limit 3")

for row in cur.fetchall():
  print row

# OUTPUT:
# (5.0999999999999996, u'setosa')
# (4.9000000000000004, u'setosa')
# (4.7000000000000002, u'setosa')
 Posted by at 1:01 下午
4月 192010
 
###################################################
# HOW TO DEFINE SQLITE FUNCTIONS WITHIN PYTHON    #
# ----------------------------------------------- #
# REFERENCE:                                      #
#  Chris Newman, SQLite, Sams Publishing          #
# ----------------------------------------------- #
# WISH LIST:                                      #
#  LOOKING FORWARD TO SUCH NEAT THING IN R        #
###################################################

import sqlite3
import math

# USE IRIS DATA AS AN EXAMPLE
con = sqlite3.connect("d:\mydb")
cur = con.cursor()

cur.execute("select * from mytab limit 3")

for row in cur:
  print row

# OUTPUT:  
# (5.0999999999999996, 3.5, 1.3999999999999999, 0.20000000000000001, u'setosa')
# (4.9000000000000004, 3.0, 1.3999999999999999, 0.20000000000000001, u'setosa')
# (4.7000000000000002, 3.2000000000000002, 1.3, 0.20000000000000001, u'setosa')

# DEFINE A MOD() FUNCTION  
def mod(x, y):
  return math.fmod(x, y)

# REGISTER THE FUNCTION
con.create_function("mod", 2, mod)

cur.execute("select sepal_length, mod(sepal_length, 2) from mytab limit 3")

for row in cur:
  print row

# OUTPUT:
# (5.0999999999999996, 1.0999999999999996)
# (4.9000000000000004, 0.90000000000000036)
# (4.7000000000000002, 0.70000000000000018)

# DEFINE A MEDIAN() AGGREGATE FUNCTION  
class median:
  def __init__(self):
    self.reset()

  def reset(self):
    self.values = []
    
  def step(self, val):
    self.values.append(float(val))

  def finalize(self):
    self.values.sort()
    n = len(self.values)
    if mod(n, 2) == 1:
      return self.values[n // 2]
    else:
      return (self.values[n // 2 - 1] + self.values[n // 2]) / 2

# REGISTER THE FUNCTION
con.create_aggregate("median", 1, median)

cur.execute("select species, median(sepal_length) from mytab group by species")
for row in cur:
  print row

# OUTPUT:  
# (u'setosa', 5.0)
# (u'versicolor', 5.9000000000000004)
# (u'virginica', 6.5)
 Posted by at 4:07 上午
8月 242009
 
#############################################
# READ STOCK PRICE FROM FINANCE.YAHOO.COM   #
#############################################

import urllib
from dateutil.relativedelta import *
from datetime import *

def GetPrice(ticker, start, end):
  stock = ticker.upper()

  m1 = int(start.split("/")[0])
  d1 = int(start.split("/")[1])
  y1 = int(start.split("/")[2])
  dt1 = date(y1, m1, d1) + relativedelta(months = -1);
  a = dt1.month
  b = dt1.day
  c = dt1.year

  m2 = int(end.split("/")[0])
  d2 = int(end.split("/")[1])
  y2 = int(end.split("/")[2])
  dt2 = date(y2, m2, d2) + relativedelta(months = -1);
  d = dt2.month
  e = dt2.day
  f = dt2.year

  url = "http://ichart.finance.yahoo.com/table.csv?s=" + stock + \
        "&d=" + str(d) + "&e=" + str(e) + "&f=" + str(f) +       \
        "&g=d&a=" + str(a) + "&b=" + str(b) + "&c=" + str(c) + "&ignore=.csv"
  data = urllib.urlopen(url)
  print data.read()
  
GetPrice("jpm", "08/01/2009", "08/10/2009")

'''
Date,Open,High,Low,Close,Volume,Adj Close
2009-08-10,42.03,43.22,42.01,42.69,43700600,42.69
2009-08-07,41.28,43.13,41.18,42.36,65696000,42.36
2009-08-06,42.28,42.46,40.22,40.75,54175600,40.75
2009-08-05,40.34,42.20,40.26,41.78,63334100,41.78
2009-08-04,39.27,40.50,39.17,40.21,43363800,40.21
2009-08-03,39.12,39.75,38.99,39.60,42957800,39.60
'''
 Posted by at 12:38 下午