常用模块-10re模块未完

一丶正则表达式
正则表达式本身是一种小型的、高度专业化的编程语言,它并不是Python的一部分。正则表达式是用于处理字符串的强大工具,拥有自己独特的语法以及一个独立的处理引擎,效率上可能不如str自带的方法,但功能十分强大。得益于这一点,在提供了正则表达式的语言里,正则表达式的语法都是一样的,区别只在于不同的编程语言实现支持的语法数量不同;但不用担心,不被支持的语法通常是不常用的部分。如果已经在其他语言里使用过正则表达式,只需要简单看一看就可以上手了。而在python中,通过内嵌集成re模块,程序员们可以直接调用来实现正则匹配。正则表达式模式被编译成一系列的字节码,然后由用C编写的匹配引擎执行。

正则表达式的大致匹配过程是:依次拿出表达式和文本中的字符比较,如果每一个字符都能匹配,则匹配成功;一旦有匹配不成功的字符则匹配失败。如果表达式中有量词或边界,这个过程会稍微有一些不同,但也是很好理解的

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

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

1.2 反斜杠的困扰

与大多数编程语言相同,正则表达式里使用""作为转义字符,这就可能造成反斜杠困扰。假如你需要匹配文本中的字符"",那么使用编程语言表示的正则表达式里将需要4个反斜杠"\":前两个和后两个分别用于在编程语言里转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。Python里的原生字符串很好地解决了这个问题,这个例子中的正则表达式可以使用r""表示。同样,匹配一个数字的"\d"可以写成r"\d"。有了原生字符串,你再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。

1.3 匹配模式

正则表达式提供了一些可用的匹配模式,比如忽略大小写、多行匹配等,这部分内容将在Pattern类的工厂方法re.compile(pattern[, flags])中一起介绍。


二丶re模块的基本使用

正则表达式是用来匹配处理字符串的 python 中使用正则表达式需要引入re模块

import re  # 第一步,要引入re模块
a = re.findall("匹配规则", "这个字符串是否有匹配规则的字符")  # 第二步,调用模块函数
print(a)  # 以列表形式返回匹配到的字符串

['匹配规则']
^元字符
[^a-z]反取
$元字符
*元字符
+元字符
?元字符(防止贪婪匹配)
{}元字符(范围)
[]元字符(字符集)
[^]
\d+
\D
\s
\S
\w
\W
()元字符(分组)
|元字符(或)


三丶re模块中常用功能函数

3.1正则表达式的两种书写方式

1.一种是直接在函数里书写规则,推荐使用

import re
a = re.findall("匹配规则", "这个字符串是否有匹配规则的字符")
print(a)

['匹配规则']
2.另一种是先将正则表达式的字符串形式编译为Pattern实例,然后使用Pattern实例处理文本并获得匹配结果(一个Match实例),最后使用Match实例获得信息,进行其他的操作。

import re

# 将正则表达式编译成Pattern对象
pattern = re.compile(r'hello')

# 使用Pattern匹配文本,获得匹配结果,无法匹配时将返回None
match = pattern.match('hello world!')

if match:
    # 使用Match获得分组信息
    print(match.group())

hello

3.2 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.L|做本地化识别(locale-aware)匹配
re.M|多行匹配,影响 ^ 和 $
re.S|使 . 匹配包括换行在内的所有字符
re.U|根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B.
re.X|该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。

3.2.1 re.S

 * 在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”当做一个普通的字符加入到这个字符串中,在整体中进行匹配。

3.2.2 re.l

 * 不区分大小写

res = re.findall(r"A", "abc", re.I)
print(res)

['a']

3.2.3 re.M

 * 将所有行的尾字母输出(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']

3.2.3 re.sub

# 要求结果:['12', '23', '34']
l = ['1 2 ', '2   3', '  3 4']
import re
print(eval(re.sub(r'\s*', '', str(l))))

['12', '23', '34']

3.3 re.match(pattern,string[,flags])函数(常用)

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'}

posted @ 2019-09-21 10:45  suren_apan  阅读(139)  评论(0编辑  收藏  举报