一丶正则表达式
正则表达式自己是一种小型的、高度专业化的编程语言,它并非Python的一部分。正则表达式是用于处理字符串的强大工具,拥有本身独特的语法以及一个独立的处理引擎,效率上可能不如str自带的方法,但功能十分强大。得益于这一点,在提供了正则表达式的语言里,正则表达式的语法都是同样的,区别只在于不一样的编程语言实现支持的语法数量不一样;但不用担忧,不被支持的语法一般是不经常使用的部分。若是已经在其余语言里使用过正则表达式,只须要简单看一看就能够上手了。而在python中,经过内嵌集成re模块,程序员们能够直接调用来实现正则匹配。正则表达式模式被编译成一系列的字节码,而后由用C编写的匹配引擎执行。python
正则表达式的大体匹配过程是:依次拿出表达式和文本中的字符比较,若是每个字符都能匹配,则匹配成功;一旦有匹配不成功的字符则匹配失败。若是表达式中有量词或边界,这个过程会稍微有一些不一样,但也是很好理解的程序员
正则表达式一般用于在文本中查找匹配的字符串。Python里数量词默认是贪婪的(在少数语言里也多是默认非贪婪),老是尝试匹配尽量多的字符;非贪婪的则相反,老是尝试匹配尽量少的字符。例如:正则表达式"ab"若是用于查找"abbbc",将找到"abbb"。而若是使用非贪婪的数量词"ab?",将找到"a"。
与大多数编程语言相同,正则表达式里使用""做为转义字符,这就可能形成反斜杠困扰。假如你须要匹配文本中的字符"",那么使用编程语言表示的正则表达式里将须要4个反斜杠"\":前两个和后两个分别用于在编程语言里转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。Python里的原生字符串很好地解决了这个问题,这个例子中的正则表达式可使用r""表示。一样,匹配一个数字的"\d"能够写成r"\d"。有了原生字符串,你不再用担忧是否是漏写了反斜杠,写出来的表达式也更直观。正则表达式
正则表达式提供了一些可用的匹配模式,好比忽略大小写、多行匹配等,这部份内容将在Pattern类的工厂方法re.compile(pattern[, flags])中一块儿介绍。编程
正则表达式是用来匹配处理字符串的 python 中使用正则表达式须要引入re模块编程语言
import re # 第一步,要引入re模块 a = re.findall("匹配规则", "这个字符串是否有匹配规则的字符") # 第二步,调用模块函数 print(a) # 以列表形式返回匹配到的字符串
['匹配规则']
^元字符
[^a-z]反取
$元字符
*元字符
+元字符
?元字符(防止贪婪匹配)
{}元字符(范围)
[]元字符(字符集)
[^]
\d+
\D
\s
\S
\w
\W
()元字符(分组)
|元字符(或)函数
1.一种是直接在函数里书写规则,推荐使用工具
import re a = re.findall("匹配规则", "这个字符串是否有匹配规则的字符") print(a)
['匹配规则']
2.另外一种是先将正则表达式的字符串形式编译为Pattern实例,而后使用Pattern实例处理文本并得到匹配结果(一个Match实例),最后使用Match实例得到信息,进行其余的操做。code
import re # 将正则表达式编译成Pattern对象 pattern = re.compile(r'hello') # 使用Pattern匹配文本,得到匹配结果,没法匹配时将返回None match = pattern.match('hello world!') if match: # 使用Match得到分组信息 print(match.group())
hello
对象
这个方法是Pattern类的工厂方法,用于将字符串形式的正则表达式编译为Pattern对象。 第二个参数flag是匹配模式,取值可使用按位或运算符'|'表示同时生效,好比re.I | re.M。另外,你也能够在regex字符串中指定模式,好比re.compile('pattern', re.I | re.M)与re.compile('(?im)pattern')是等价的。字符串
下表是全部的正则匹配模式:
修饰符|描述
-|:-:|-:
re.I|使匹配对大小写不敏感
re.L|作本地化识别(locale-aware)匹配
re.M|多行匹配,影响 ^ 和 $
re.S|使 . 匹配包括换行在内的全部字符
re.U|根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B.
re.X|该标志经过给予你更灵活的格式以便你将正则表达式写得更易于理解。
* 在Python的正则表达式中,有一个参数为re.S。它表示 “.” 的做用扩展到整个字符串,包括“\n”。看以下代码:
import re a = '''asdfhellopass: worldaf ''' b = re.findall('hello(.*?)world', a) c = re.findall('hello(.*?)world', a, re.S) print('b is ', b) print('c is ', c)
b is [] c is ['pass:\n ']
正则表达式中,“.”的做用是匹配除“\n”之外的任何字符,也就是说,它是在一行中进行匹配。这里的“行”是以“\n”进行区分的。a字符串有每行的末尾有一个“\n”,不过它不可见。
若是不使用re.S参数,则只在每一行内进行匹配,若是一行没有,就换下一行从新开始,不会跨行。而使用re.S参数之后,正则表达式会将这个字符串做为一个总体,将“\n”当作一个普通的字符加入到这个字符串中,在总体中进行匹配。
* 不区分大小写
res = re.findall(r"A", "abc", re.I) print(res)
['a']
* 将全部行的尾字母输出(python3+已经无效)
s = '12 34/n56 78/n90' re.findall(r'^/d+', s, re.M) # 匹配位于行首的数字 # ['12', '56', '90'] re.findall(r'/A/d+', s, re.M) # 匹配位于字符串开头的数字 # ['12'] re.findall(r'/d+$', s, re.M) # 匹配位于行尾的数字 # ['34', '78', '90'] re.findall(r'/d+/Z', s, re.M) # 匹配位于字符串尾的数字 # ['90']
# 要求结果:['12', '23', '34'] l = ['1 2 ', '2 3', ' 3 4'] import re print(eval(re.sub(r'\s*', '', str(l))))
['12', '23', '34']
match,从头匹配一个符合规则的字符串,从起始位置开始匹配,匹配成功返回一个对象,未匹配成功返回None
match(pattern, string, flags=0)
* pattern: 正则模型
* string : 要匹配的字符串
* falgs : 匹配模式
注意:match()函数 与 search()函数基本是同样的功能,不同的就是match()匹配字符串开始位置的一个符合规则的字符串,search()是在字符串全局匹配第一个合规则的字符串
import re # 无分组 origin = "hello egon bcd egon lge egon acd 19" r = re.match("h\w+", origin) # match,从起始位置开始匹配,匹配成功返回一个对象,未匹配成功返回None print(r.group()) # 获取匹配到的全部结果,无论有没有分组将匹配到的所有拿出来 print(r.groups()) # 获取模型中匹配到的分组结果,只拿出匹配到的字符串中分组部分的结果 print(r.groupdict()) # 获取模型中匹配到的分组结果,只拿出匹配到的字符串中分组部分定义了key的组结果
hello () {}
# 有分组 # 为什么要有分组?提取匹配成功的指定内容(先匹配成功所有正则,再匹配成功的局部内容提取出来) r = re.match("h(\w+)", origin) # match,从起始位置开始匹配,匹配成功返回一个对象,未匹配成功返回None print(r.group()) # 获取匹配到的全部结果,无论有没有分组将匹配到的所有拿出来 print(r.groups()) # 获取模型中匹配到的分组结果,只拿出匹配到的字符串中分组部分的结果 print(r.groupdict()) # 获取模型中匹配到的分组结果,只拿出匹配到的字符串中分组部分定义了key的组结果
hello ('ello',) {}
# 有两个分组定义了key # 为什么要有分组?提取匹配成功的指定内容(先匹配成功所有正则,再匹配成功的局部内容提取出来) # ?P<>定义组里匹配内容的key(键),<>里面写key名称,值就是匹配到的内容 r = re.match("(?P<n1>h)(?P<n2>\w+)", origin) print(r.group()) # 获取匹配到的全部结果,无论有没有分组将匹配到的所有拿出来 print(r.groups()) # 获取模型中匹配到的分组结果,只拿出匹配到的字符串中分组部分的结果 print(r.groupdict()) # 获取模型中匹配到的分组结果,只拿出匹配到的字符串中分组部分定义了key的组结果
hello ('h', 'ello') {'n1': 'h', 'n2': 'ello'}