python之正则表达式

http://wiki.ubuntu.org.cn/Python%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F%E6%93%8D%E4%BD%9C%E6%8C%87%E5%8D%97

http://www.cnblogs.com/huxi/archive/2010/07/04/1771073.html

在使用 re 模块之前,先考虑一下你的问题是否可以用更快、更简单的字符串方法来解决

数量词的贪婪模式与非贪婪模式

正则表达式通常用于在文本中查找匹配的字符串。Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能多的字符;非贪婪的则相反,总是尝试匹配尽可能少的字符。例如:正则表达式"ab*"如果用于查找"abbbc",将找到"abbb"。而如果使用非贪婪的数量词"ab*?",将找到"a"。

用a[bcd]*b匹配字符串 "abcbd"将会匹配到abcb

正则表达式元字符

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

^ 匹配字符串的开始
$ 匹配字符串的结束
对于前一个字符字符重复0次到1次
* 对于前一个字符重复0次到无穷次
+ 对于前一个字符重复1次到无穷次
{m} 对于前一个字符重复m次
{m,n} 对前一个字符重复为m到n次 (注意m,n之间不能有空格)

. 匹配除换行符以外的任意字符,而且可以通过re.S匹配换行符

[...] 字符集:

所谓字符类别就是你想匹配的一个字符集

[abc] 将匹配"a", "b", 或 "c"中的任意一个字符;也可以用区间[a-c]来表示同一字符集

ps:元字符在类别里并不起作用
例如,[akm$]将匹配字符"a", "k", "m", 或 "$" 中的任意一个;
"$"通常用作元字符,但在字符类别里,其特性被除去,恢复成普通字符。

除了^、]、-

可以用补集来匹配不在区间范围内的字符
其做法是把"^"作为类别的首个字符;其它地方的"^"只会简单匹配 "^"字符本身。
例如,[^5] 将匹配除 "5" 之外的任意字符,[^5^]将匹配除"5","^"之外的任意字符

 “”:做为 Python 中的字符串字母,反斜杠后面可以加不同的字符以表示不同特殊意义。它也可以用于取消所有的元字符,这样你就可以在模式中匹配它们了。举个例子,如果你需要匹配字符 "[" 或 "",你可以在它们之前用反斜杠来取消它们的特殊意义: [ 或 \。 

一些用 "" 开始的特殊字符所表示的预定义字符集通常是很有用的,象数字集,字母集,或其它非空字符集。下列是可用的预设特殊字符:

d 匹配任何十进制数;它相当于类 [0-9]。
D 匹配任何非数字字符;它相当于类 [^0-9]。
s 匹配任何空白字符;它相当于类 [ fv]。
S 匹配任何非空白字符;它相当于类 [^ fv]。
w 匹配任何字母数字字符;它相当于类 [a-zA-Z0-9_]。
W 匹配任何非字母数字字符;它相当于类 [^a-zA-Z0-9_]。

"or" 操作符。如果 A 和 B 是正则表达式,A|B 将匹配任何匹配了 "A" 或 "B" 的字符串。

这是个零宽界定符(zero-width assertions)只用以匹配单词的词首和词尾。单词被定义为一个字母数字序列,因此词尾就是用空白符或非字母数字符来标示的。

另一个零宽界定符(zero-width assertions),它正好同  相反,只在当前位置不在单词边界时匹配。

原生字符串

想写一个 RE 以匹配字符串 "section",可能是在一个 LATEX 文件查找。为了要在程序代码中判断,首先要写出想要匹配的字符串。接下来你需要在所有反斜杠和其它元字符前加反斜杠来取消其特殊意义,结果要匹配的字符串就成了"\section"。 当把这个字符串传递给re.compile()时必须还是"\section"。然而,作为Python的字符串实值(string literals)来表示的话,"\section"中两个反斜杠还要再次取消特殊意义,最后结果就变成了"\\section"。

解决的办法就是为正则表达式使用 Python 的 raw 字符串表示;在字符串前加个 "r" 反斜杠就不会被任何特殊方式处理,所以 r" " 就是包含"" 和 "n" 的两个字符,而 " " 则是一个字符,表示一个换行。正则表达式通常在 Python 代码中都是用这种 raw 字符串表示。
简单地说,为了匹配一个反斜杠,不得不在 RE 字符串中写 '\\',因为正则表达式中必须是 "\",而每个反斜杠在常规的 Python 字符串实值中必须表示成 "\"。在 REs 中反斜杠的这个重复特性会导致大量重复的反斜杠,而且所生成的字符串也很难懂。

常规字符串 Raw 字符串
"ab*" r"ab*"
"\\section" r"\section"
"\w+\s+\1" r"w+s+1"

匹配模式

re.I(re.IGNORECASE): 忽略大小写
re.M(MULTILINE): 多行模式,改变'^'和'$'的行为(开启re.M后,"^" 匹配字符串的开始和字符串中每行的开始。同样的, $ 元字符匹配字符串结尾和字符串中每行的结尾)
re.S(DOTALL): 点任意匹配模式,改变'.'的行为(.可以跨行匹配)

常用的正则表达式处理函数

1.re.search(pattern, string, flags=0)
re.search 函数会在字符串内查找模式匹配,直至找到第一个匹配然后返回,如果字符串没有匹配,则返回None。

第一个参数:规则
第二个参数:表示要匹配的字符串
第三个参数:标致位,用于控制正则表达式的匹配方式

内置method:

group():返回被 RE 匹配的字符串

start():返回匹配开始的位置

end():返回匹配结束的位置

span():返回一个元组包含匹配 (开始,结束) 的位置

name="Hello,My name is kuangl,nice to meet you..."
k=re.search(r'k(uan)gl',name)
if k:
    print k.group(0),k.group(1)
else:
    print "Sorry,not search!"
------------------------- 
kuangl uan

2.re.match(pattern, string, flags=0)
re.match 尝试从字符串的开始匹配一个模式,也等于说是匹配第一个单词

method:同serach

name="Hello,My name is kuangl,nice to meet you..."
k=re.match(r"(H....)",name)
if k:
    print k.group(0), k.group(1)
else:
    print "Sorry,not match!"
--------------------------
Hello Hello

re.match与re.search的区别:re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。

3.re.findall(pattern, string, flags=0)
返回的结果是一个列表,建中存放的是符合规则的字符串,如果没有符合规则的字符串呗找到,就会返回一个空值。

mail='<user01@mail.com> <user02@mail.com> user04@mail.com'
re.findall(r'(w+@mail.[a-z]{3})',mail)
----------------------------------------------------
['user01@mail.com', 'user02@mail.com', 'user04@mail.com']

4、re.sub(pattern, repl, string, count=0)

re.sub处理详解
re.sub 用于替换字符串的匹配项
第一个参数:规则
第二个参数:可以是字符串,也可以是函数
第三个参数:原字符串
第四个参数:替换个数。默认为0,表示每个匹配项都替换

test="Hi, nice to meet you where are you from?"
re.sub(r's','-',test)
re.sub(r's','-',test,5) 
---------------------------------------
'Hi,-nice-to-meet-you-where-are-you-from?'
'Hi,-nice-to-meet-you-where are you from?'

5.re.split(pattern, string, maxsplit=0)

test="Hi, nice to meet you where are you from?"
re.split(r"s+",test)
re.split(r"s+",test,3) 
--------------------------------------------------
['Hi,', 'nice', 'to', 'meet', 'you', 'where', 'are', 'you', 'from?']
['Hi,', 'nice', 'to', 'meet you where are you from?']

6.re.compile(pattern, flags=0)
可以把正则表达式编译成一个正则对象

pattern = re.compile(r'hello')
match = pattern.match('hello world!')
print match.group()
-------------------------------------
hello

其它

给匹配的组命名:(?P<name>...)

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

逆向引用

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

如果组 1 的内容能够在当前位置找到的话,1 就成功否则失败。记住 Python 字符串也是用反斜杠加数据来允许字符串中包含任意字符的,所以当在 RE 中使用逆向引用时确保使用 raw 字符串。

2015-05-09

 

原文地址:https://www.cnblogs.com/whuyt/p/4491143.html