正则表达式

# 原创,转载请联系

1.匹配单个字符

字符功能
. 匹配任意1个字符(除了\n)
[ ] 匹配[ ]中列举的字符。[ ]里面有^表示取反
\d 匹配数字,即0-9
\D 匹配非数字,即不是数字
\s 匹配空白,即 空格,tab键
\S 匹配非空白
\w 匹配单词字符,即a-z、A-Z、0-9、_
\W 匹配非单词字符

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

2.匹配多个字符

 

字符功能
* 匹配前一个字符出现0次或者无限次,即可有可无
+ 匹配前一个字符出现1次或者无限次,即至少有1次
? 匹配前一个字符出现1次或者0次,即要么有1次,要么没有
{m} 匹配前一个字符出现m次
{m,n} 匹配前一个字符出现从m到n次

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

3.匹配开头结尾

字符功能
^ 匹配字符串开头(这个东西很少用到,因为默认匹配开头的)
$ 匹配字符串结尾

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

4.匹配分组

字符功能
| 匹配左右任意一个表达式
(ab) 将括号中字符作为一个分组
\num 引用分组num匹配到的字符串
(?P<name>) 分组起别名
(?P=name) 引用别名为name分组匹配到的字符串

 这个就稍微有点难度了。

(1) | ,表示匹配任意一个表达式。

示例: 请写出能同时验证163或者126合法邮箱的正则表达式
匹配规则:每个邮箱必须有@符号,且@符号之前需有4到20位单词字符)

import re
web_list = ["chichungceng@163.com","237320770@qq.com",
            "hfdsj@126.com.cn","hh#djsa@126.com","shdABC@126.com"]

for web in web_list:
    ret = re.match("\w{4,20}@163\.com$|\w{4,20}@126\.com$",web)
    if ret:
        print(ret.group())

输出:
chichungceng@163.com
shdABC@126.com

(2) (ab) ,将括号内的字符作为一个分组

上面的例子,都是匹配邮箱地址,只是一个是163,一个是126。正则表达式的重复部分特别多,这时候就需要用到分组了。看下示例。

示例: 请写出能同时验证163或者126或者qq合法邮箱的正则表达式
匹配规则:每个邮箱必须有@符号,且@符号之前需有4到20位单词字符)

import re

web_list = ["chichungceng@163.com","237320770@qq.com",
            "hfdsj@126.com.cn","hh#djsa@126.com","shdABC@126.com"]

for web in web_list:
    ret = re.match("\w{4,20}@(163|126)\.com$",web)
    if ret:
        print(ret.group())

输出:
chichungceng@163.com
shdABC@126.com

当我们想拿出来邮箱的前缀163或者126的时候呢?应该怎么办呢?

答案是:ret.group(1)

为什么是1呢?

因为匹配一整个正则表达式就是0,所以ret.group(0)实际上相当于ret.group()。然后从左到右,每个分组依次是1,2......

(3) \num ,引用分组num匹配到的字符串

引用的作用就是避免重复编写已经编写过的正则表达式规则,可以更加省时省力。

经常应用到网页代码的筛选中。因为网页的代码通常都是对称的,因此可以用前面编写过的正则表达式规则。

 

import re

ret1 = re.match("<(\w+)>.*</\\1>","<h1>jdksaljd_HJS545</h1>")

"""如果前面有r,代表原生字符串。后面的\1就不需要转义了。
\1要转义是因为他本来的输出不是我们所见到的\1,而是其他东西。
有兴趣可以尝试输出一下。
所以如果开头不加r,\1是需要转义的"""
ret2 = re.match(r"<(\w+)>.*</\1>","<h1>jdksaljd_HJS545</h1>")
print(ret1.group())
print(ret2.group())

输出:
<h1>jdksaljd_HJS545</h1>
<h1>jdksaljd_HJS545</h1>

(4) (?P<name>) ,起别名。(?P=name) ,引用别名

import re

ret2 = re.match(r"<(?P<p1>\w+)>.*</(?P=p1)>","<h1>jdksaljd_HJS545</h1>")

print(ret2.group())

输出:
<h1>jdksaljd_HJS545</h1>

如果组太多了,很难数的时候,可以给组起别名,下面引用就可以用组的内容了。

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

5.re模块的常用函数

(1)match

从头到尾的匹配,上面例子太多了,所以这里就不说了。

(2)search

在目标字符串里寻找符合正则表达式的内容。

import re

ret = re.search("\d+","我的期末考试是111分。")
print(ret.group())

输出:
111

\d+为什么不是匹配出1,11,而是111呢?

其实这是正则表达式的贪婪原则。

能匹配多点就匹配多点。

(3)findall

在目标字符串里寻找符合正则表达式的全部内容,并且返回一个列表。

import re

ret = re.findall("\d+","我的语文98分,数学100分,英语60分")
print(ret)

输出:
['98', '100', '60']

(4)sub

将匹配到的数据进行替换

import re

ret = re.sub("\d+","60","天啊,我的英语100分,语文100分")
print(ret)

输出:
天啊,我的英语60分,语文60分

这也是贪婪原则。

(5)split :按规则分离字符串,返回的是分离后的列表

import re

ret = re.split(",|:","天啊,我的英语100分:语文100分")
print(ret)

输出:
['天啊,我的英语100分', '语文100分']

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

6.解决正则表达式的贪婪问题

(1)针对单个数据

在"*","?","+","{m,n}"后面加上?,使贪婪变成非贪婪。

import re

ret1 = re.search("\d+?","我的学号是123")
ret2 = re.search("\d+","我的学号是123")

print(ret1.group())
print(ret2.group())

输出:
1
123

(2)针对多个数据

这时候就需要用到函数了。

import re

def add(a):
   num = int(a.group())
   num += 1
   return str(num)

content = "文章阅读数为500,点赞数为50"
ret = re.sub("\d+",add,content)
print(ret)

输出:
文章阅读数为501,点赞数为51

这里需要注意一下!

 

posted @ 2018-08-29 22:50  苦瓜爆炒牛肉  阅读(246)  评论(0编辑  收藏  举报