1.数量词的贪婪模式与非贪婪模式
正则表达式通常用于在文本中查找匹配的字符串。Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能多的字符;非贪婪的则相反,总是尝试匹配尽可能少的字符。例如:正则表达式"ab*"如果用于查找"abbbc",将找到"abbb"。而如果使用非贪婪的数量词"ab*?",将找到"a"。
2.反斜杠的困扰
与大多数编程语言相同,正则表达式里使用"\"作为转义字符,这就可能造成反斜杠困扰。假如你需要匹配文本中的字符"\",那么使用编程语言表示的正则表达式里将需要4个反斜杠"\\\\":前两个和后两个分别用于在编程语言里转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。Python里的原生字符串很好地解决了这个问题,这个例子中的正则表达式可以使用r"\\"表示。同样,匹配一个数字的"\\d"可以写成r"\d"。有了原生字符串,你再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。
3.Python常用正则表达式
一定要掌握的几个
? 匹配 0 个或一个, 另外在非贪婪模式,最小化匹配时有用。python 默认是贪婪模式匹配的。
. 匹配任何非换行字符,但可以通过 re.S 绕过这一点.
+ 匹配一个或多个
* 匹配0个或多个.
[] 匹配里面的任何一个字符
[^ ] 不匹配里面的任何一个字符. 在 [] 中所有字符均失去特殊意义,比如'.' 不再代表仍何非换行字符,就是代表'.' 号 .
{} 匹配个数 ,比如{3}表示匹配3个,{1,3} 表示可以匹配1个到3个。
^ 匹配字符串开始
$ 匹配字符串结束
\d 匹配任何数字,也就是0-9
\D 匹配仍何非数字 [^0-9] 与 \d 相反
\w 匹配数字和字幕 0-9 a-z A-Z
\W 与\w 相反
\s 匹配空白字符,比如 \n \t \r \v \f
\S 与 \s 相反
\ 本身,转义符. 比如要明确的匹配'.'号,就应该用'\.' 否则 '.' 代表匹配任何非换行符了
4. re模块
Python通过re模块提供对正则表达式的支持。使用re的一般步骤是先将正则表达式的字符串形式编译为Pattern实例,然后使用Pattern实例处理文本并获得匹配结果(一个Match实例),最后使用Match实例获得信息,进行其他的操作。
pattern= re.compile(r'hello') # 将正则表达式编译成Pattern对象
match= pattern.match('hello world!') # 使用Pattern匹配文本,获得匹配结果,无法匹配时将返回None
if match:
print match.group() # 使用Match获得分组信息
# hello
re.compile(strPattern[, flag]):
这个方法是Pattern类的工厂方法,用于将字符串形式的正则表达式编译为Pattern对象。 第二个参数flag是匹配模式,取值可以使用按位或运算符'|'表示同时生效,比如re.I | re.M。另外,你也可以在regex字符串中指定模式,比如re.compile('pattern', re.I | re.M)与re.compile('(?im)pattern')是等价的。
常用可选值有:
- re.I(re.IGNORECASE): 忽略大小写
- M(MULTILINE): 多行模式,改变'^'和'$'的行为
- S(DOTALL): 点任意匹配模式,改变'.'的行为
re提供了众多模块方法用于完成正则表达式的功能。这些方法可以使用Pattern实例的相应方法替代,唯一的好处是少写一行re.compile()代码,但同时也无法复用编译后的Pattern对象。这些方法将在Pattern类的实例方法部分一起介绍。如上面这个例子可以简写为:
m= re.match(r'hello','hello world!')
print m.group()
re模块还提供了一个方法escape(string),用于将string中的正则表达式元字符如*/+/?等之前加上转义符再返回,在需要大量匹配元字符时有那么一点用。
re.match详解
re.match 尝试从字符串的开始匹配一个模式。
import re
text = 'JGood is a handsome boy, he is cool, clever, and so on...'
m = re.match(r'(\w+)\s(\w+)', text)
if m:
print m.group(0), '\n', m.group(1)
else:
print'not match'
re.search
re.search函数会在字符串内查找模式匹配,只到找到第一个匹配然后返回,如果字符串没有匹配,则返回None。
import re
text = “JGood is a handsome boy, he is cool, clever, and so on…”
m = re.search(r’\shan(ds)ome\s’, text)
if m:
print m.group(0), m.group(1)
else:
print ‘not search’
re.match与re.search的区别:re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。
re.sub
re.sub用于替换字符串中的匹配项。下面一个例子将字符串中的空格 ‘ ‘ 替换成 ‘-’ :
import re
text = “abcde”
print re.sub(r’\s+’, ‘-’, text)
re.sub(r’\s’, lambda m: ‘[' + m.group(0) + ']‘, text, 0);将字符串中的空格’ ‘替换为’[ ]‘。
re.split
可以使用re.split来分割字符串,如:re.split(r’\s+’, text);将字符串按空格分割成一个单词列表。
re.findall
re.findall可以获取字符串中所有匹配的字符串。如:re.findall(r’\w*oo\w*’, text);获取字符串中,包含’oo’的所有单词。
5. 常用正则表达式例子
5.1 数字
import re
nStr = '123'
p = re.compile(’^\d+$’,re.S) #非负整数(正整数与零)
#p = re.compile(’^[0-9]*[1-9][0-9]*$’,re.S) #正整数(不包括零在内)
#p = re.compile(’^((-\d+)|(0+))$’,re.S) #非正整数(负整数+0)
#p = re.compile(’^-[0-9]*[1-9][0-9]*$’,re.S) #负整数
#p = re.compile(’^-?\d+$’,re.S) #整数
#p = re.compile(’^\d+(\.\d+)?$’,re.S) #非负浮点数(正浮点数 + 0)
#p = re.compile(’^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$’,re.S) #正浮点数
#p = re.compile(’^((-\d+(\.\d+)?)|(0+(\.0+)?))$’,re.S) #非正浮点数(负浮点数 + 0)
# p = re.compile(’^(-?\d+)(\.\d+)?$’,re.S) #浮点数
if p.match(nStr):
print 'exists'
else:
print 'not'
5.2 字符相关
26个英文字母组成的字符串
import re
nStr = 'abck'
p = re.compile('^[A-Za-z]+$',re.S)
if p.match(nStr):
print “exists”
else:
print “not”
如果是大写的话就是:^[A-Z]+$
如果是小写的话就是:^[a-z]+$
如果是数字与字母组合:^[A-Za-z0-9]+$
如果由数字、26个字母、或下划线组成的:^\w+$
5.3 HTML相关
5.3.1 匹配<script>标签的
#coding:utf-8
import re
nStr = “<script src=’…js’></script>”
p = re.compile(’<\s*script[^>]*>[^<]*<\s*/\s*script\s*>’,re.I)
if p.match(nStr):
print “exists”
else:
print “not”
5.3.2 匹配<style>标签
#coding:utf-8
import re
nStr = '<style 11> <11</style>'
p = re.compile('<\s*style[^>]*>[^<]*<\s*/\s*style\s*>',re.I)#[^<]表示所有的非<符号的字符
if p.match(nStr):
print'exists'
else:
print'not'
5.3.3 匹配HTML标签
#coding:utf-8
import re
nStr = '<div>'
p = re.compile('</?\w+[^>]*>',re.I)
if p.match(nStr):
print 'exists'
else:
print 'not'
5.4 匹配EMAIL地址
import re
p = re.compile('^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$',re.S)
if p.match(nStr):
print 'exists'
else:
print 'not'
5.5 匹配URL
import re
nStr = 'http://localhost'
p = re.compile(’^[a-zA-z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\S*)?$’,re.S)
if p.match(nStr):
print 'exists'
else:
print 'not'