正则表达式:百度来的解释是用一段通用、约定格式和规则的代码来对符合规则的文本进行检索和替换。
第一次用到正则表达式是在爬虫里,在爬取一个网站的html后,需要去掉html里标签内容只留下文本内容。用正则表达式就能很好解决这个问题。我自己理解的正则表达式就是根据制定的规则来匹配特定的字符串。所以我们需要注意的就是正则表达式的匹配规则。
单字符匹配规则
字符 | 功能 |
---|---|
. | 匹配任意1个字符(除了\n) |
[ ] | 匹配[ ]中列举的字符 |
\d | 匹配数字,即0-9 |
\D | 匹配非数字,即不是数字 |
\s | 匹配空白,即空格,tab等 |
\S | 匹配非空白 |
\w | 匹配单词字符,即a-z,A-Z,0-9,__ |
\W | 匹配非单词字符 |
注:python中避免字符串的字符被转义,可在字符串前面加上个r。
举几个栗子,match函数的作用是 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。如果匹配成功就返回一个Math对象,该对象里的group返回的是匹配成功的字符串。
import re
s = 'qwer'
result = re.match(r'..', s)
print(result.group())
#输出:qw
import re
s = '12345678912'
result = re.match(r'[12]\d\d\w', s)
print(result.group())
#输出:1234
数量描述规则
字符 | 功能 |
---|---|
* | 匹配前一个字符出现0次或者无限次,即可有可无 |
+ | 匹配前一个字符出现1次或者无限次,即至少1次 |
? | 匹配前一个字符出现1次或者0次,即要么1次要么没有 |
{m} | 匹配前一个字符出现m次 |
{m,} | 匹配前一个字符至少出现m次 |
{m,n} | 匹配前一个字符出现从m到n次 |
再举几个栗子
import re
s = '1233344aa'
result = re.match(r'[12]\d*\w', s)
print(result.group())
#输出:1233344a
import re
s = '13333aa'
result = re.match(r'[12]\d{3,5}\w', s)
print(result.group())
#:输出13333a
表示边界规则
字符 | 功能 |
---|---|
^ | 匹配字符串的开头(在[]表示非) |
$ | 匹配字符串结尾 |
\b | 匹配一个单词的边界 |
\B | 匹配非单词边界 |
注: 加不加^和$的区别
①[a-z]可以用来匹配任意位置上的小写字母:"…a…"
②^[a-z]只能匹配以小写字母为行首的行:“a”
③[a-z]$只能匹配以小写字母为行尾的行:"…a"
④^ [a-z]只能匹配以小写字母为行首的行:“a”
\b和\B的区别在于:\b匹配时其要匹配的字符串在源字符串s中的位置左右不能出现英文字母,相反的\B的周围必须是英文字母。(是不是一个单词由该词左右是不是空格所决定的)
re.findall()的作用是从指定字符串找到符合要求的所有字符串。
example
import re
s = 'apple1 banana2 pear3'
result = re.findall(r'\w+\b', s)
print(result)
#输出:['apple1', 'banana2', 'pear3']
import re
s = 'apple1 banana2 pear3'
result = re.findall(r'\w+\B', s)
print(result)
#输出:['apple', 'banana', 'pear']
匹配分组规则
字符 | 功能 |
---|---|
| | 匹配左右任意一个表达式 |
(ab) | 将括号中字符作为一个分组 |
\num | 引用分组num匹配到的字符串(前面出现的括号内容可以用\num表示) |
(?p) | 分组起别名 |
(?p=name) | 引用别名为name分组匹配到的字符串 |
再再再举几个栗子
import re
# 匹配0-100之间的数字
s = '25'
result = re.match(r'[1-9]?\d?$|100$', s)
print(result.group())
#输出: 25
re.sub("", “”, “”)的作用是替换文本中的指定的字符串,第一个参数是指定规则的正则表达式,第二个参数是需要替换的字符串或者是一个函数,第三个是将遍历的字符串。
import re
# 删除一些html标签
s = '''<h1>
渐进式<br>JavaScript 框架
</h1>'''
result = re.sub(r'<(.+)>|</\1>','', s)
print(result)
#输出: 渐进式JavaScript 框架
import re
# 删除一些html标签
s = '''<h1>
渐进式<br>JavaScript 框架
</h1>'''
result = re.sub(r'<(?P<key1>.+)>|</(?P=key1)>','', s)
print(result)
#输出: 渐进式JavaScript 框架
贪婪模式
我的理解就是字符串自左向右尽可能多的匹配。
这样可能还是难以理解,举个例子。还是上文中的去除文本中的html标签。
import re
s = '''<h1>渐进式<br>JavaScript 框架</h1>'''
result = re.sub(r'<.+>', '', s)
print(result)
# 输出空白
本来的目的是去除带有<>的字符串,但是因为贪婪模式是开启的。<字符被匹配到之后就会一直向后寻找>,找到渐前面的>之后并不算完成,因为贪婪模式是要符合最大匹配原则的,所以就会找到最后一个字符>,最终完成匹配。
解决的办法就是关闭贪婪模式,当在*或者+后面加上?就算关闭了。
import re
# 关闭贪婪模式
s = '''<h1>渐进式<br>JavaScript 框架</h1>'''
result = re.sub(r'<.+?>', '', s)
print(result)
#输出:渐进式JavaScript 框架