同志们,为什么我爱python爱的深沉,因为就是我被这个‘少女’迷倒。下面来看看它的‘活好’好在哪(这只是勾起大家读书的欲望而已,相信我)
模块re:正则表达式(Regexp/Regex)
正则表达式是一种用形式化语法描述的文本匹配模式。模式会被解释为一组指令,然后执行这些指令并提供一个字符串作为输入,将生成一个匹配子集或者生成原字符串的一个修正版本。
1.查找文本中的模式的函数:search(pattern,text)函数(单对象匹配,匹配到就停止,即使后面还有也不进行)
在该函数中我们会引入一个Match对象,当如果找到该模式(pattern)时,就会返回一个Match对象,如果没有找到,search()函数将返回None。一定要注意Match对象,它有许多方法和特性,它包含着有关匹配性质的信息:
(1)match.string:原输入字符串
(2)match.start()/match.end():分别代表文本中指定模式的开始与结束,和切片一样,也是顾左不顾右。
(3)match.re.pattern:表示当前我们给定的模式
2.编译表达式(预编译):compile()函数
尽管re模块包含了许多模块级函数,但对程序频繁使用的表达式而言,预编译它会更加便利。compile()函数会把一个字符串转换成Regexp Object(正则表达式对象)。预编译的好处在于我们可以把编译工作转移到应用开始时,而不是当一个程序响应一个用户动作时才编译。举个例子:
import re
#编译
regexes = [re.compile(p) for p in ['this','that']] #利用列表推导式,进行迭代
text = 'This is a sample practice.'
for match in regexes:
print('Seeking "{}" ->'.format(match.pattern))
if match.search(text):
print("match!!")
else:
print("no match!")
3.多重匹配:
findall(pattern,text) 返回输入中与模式匹配而且不重叠的所有字符串
finditer(pattern,text) 返回一个迭代器,它会生成Match实例,而不像findall()函数那样返回字符串
结合上述的模块级函数,我们就可以做一个可以简单匹配文本的程序:
#给定模式,搜索文本中的匹配情况
def test_pattern(text,patterns):
for pattern,desc in patterns: #解包,分别把模式和说明赋值给两个变量
print('Text -> {!r}'.format(text))
print('Seeking -> {!r}'.format(pattern))
pattern = re.compile(pattern) #预编译模式
for match in pattern.finditer(text):
s = match.start() #确定每一个开始位置
e = match.end() #确定每一个结束位置
sub_str = text[s:e] #锁定匹配字符串
prefix = '*' * s
print("{}{!r}".format(prefix,sub_str))
print()
return
test_pattern('ababaaaababbb',[('ab','匹配一个ab'),])
模式语法:
1.重复
(pattern)? | (pattern)+ | (pattern)* | (pattern){m} | (pattern){m,n} |
重复零次或一次 | 重复一次或多次 | 重复零次或多次 | 重复m次 | 重复m<=x<=n次 |
在处理重复指令的时候,re在匹配模式时会尽可能多地消费输入,这种‘贪心’行为功能会导致单个匹配会减少,或者匹配结果可能包含比预期更多的输入文本。所以可以在重复指令后面添加?来关闭这种贪心行为。
值得我们注意的是,(ab)*和ab*它们的含义分别是允许匹配重复零次或者一次ab,后者为匹配一个a和可以重复零次或者一次b 2.字符集:它是一组字符,包含可以与模式中当前位置匹配的所有字符
注意<当前位置>这几个字眼,意思就是说就算我们给定的模式为[ab],程序也会解释为此位置可以放置a或者b
指定字符 | [ ] |
排除字符 | [^ ] |
特殊情况 | . |
3.字符区间:用于定义字符集的一种简洁的语法
- [a-z]:代表的就是小写的ASCII字母
- [A-Z]:代表的就是大写的ASCII字母
4.转义码:
转义码 | 含义 |
\d | 数字 |
\D | 非数字 |
\s | 空白符(制表符,空格,换行等) |
\S | 非空白符 |
\w | 字母数字 |
\W | 非字母数字 |
在字符串前加一个反斜杠(\)来指示转义,但遗憾的是。反斜杠本身在正常的python字符串中也必须转义,所以为了避免糟糕的情况,可以通过原始字符串(raw)。
在简洁程度和作用范围中:
重复<字符集<字符区间<转义码
以上的模式语法大家都可以在我们定义的test_pattern函数实验。
限制搜索 :
在有些情况下,我们可能不必全部搜索,或者要模式和文本完全吻合,这就需要用到限制搜索函数。
re.match(pattern,string):要求模式匹配在输出开头,如果匹配到就返回匹配信息,如果不符合要求则返回None
re.fullmatch(pattern,string):要求输入的整个字符串和模式匹配