# Python中的正则表达式
# 什么是正则表达式
世界上分为两种人,一种是懂正则表达式的,一种是不懂正则表达式的
按照一定的规则,从某个字符串中匹配出想要的数据,这个规则就是正则表达式
# 正则表达式常用的匹配规则
# 匹配某个字符串
text = 'hello'
ret = re.match('he', text)
print(ret.group())
# >> he
1
2
3
4
2
3
4
# 点(.
) 匹配任意的字符串
text = 'ab'
ret = re.match('.', text)
print(ret.group())
# >> a
1
2
3
4
2
3
4
# \d
匹配任意的数字
text = '123'
ret = re.match('\d', text)
print(ret.group())
# >> 1
1
2
3
4
2
3
4
# \D
匹配任意的非数字
text = "a"
ret = re.match('\D',text)
print(ret.group())
# >> a
1
2
3
4
2
3
4
如果text为一个数字,那么就匹配不成功了
text = "1"
ret = re.match('\D',text)
print(ret.group())
# >> AttributeError: 'NoneType' object has no attribute 'group'
1
2
3
4
2
3
4
# \s
匹配的是空白字符串(包括:\n,\t,\r,空格)
text = "\t"
ret = re.match('\s',text)
print(ret.group())
# >> 此处是一个空白
1
2
3
4
2
3
4
# \w
匹配的是 a-z 和 A-Z 以及数字和下划线
text = "_"
ret = re.match('\w',text)
print(ret.group())
# >> _
1
2
3
4
2
3
4
如果要匹配一个其他的字符,那么就匹配不到
text = "+"
ret = re.match('\w',text)
print(ret.group())
# >> AttributeError: 'NoneType' object has no attribute
1
2
3
4
2
3
4
# \W
匹配的是和 \w
相反的
text = "+"
ret = re.match('\W',text)
print(ret.group())
# >> +
1
2
3
4
2
3
4
如果你的text是一个下划线或者英文字符,那么就匹配不到了
text = "_"
ret = re.match('\W',text)
print(ret.group())
# >> AttributeError: 'NoneType' object has no attribute
1
2
3
4
2
3
4
# []
组合的方式,只要满足中括号中的某一项都算匹配成功
text = "027-88888888"
ret = re.match('[\d\-]+',text)
print(ret.group())
# >> 027-88888888
1
2
3
4
2
3
4
其实可以使用中括号代替几种默认的匹配规则
\d
:[0-9]\D
:0-9\w
:[0-9a-zA-Z_]\W
:
# 匹配多个字符
# *
:可以匹配0或者任意多个字符
text = '8888'
ret = re.match('\d*',text)
print(ret.group())
# >> 8888
1
2
3
4
2
3
4
以上因为匹配的要求是 \d
,那么就要求是数字,后面跟了一个星号,就可以匹配到8888这四个字符
# +
:可以匹配1个或者多个字符,最少一个
text = "abc"
ret = re.match('\w+',text)
print(ret.group())
# >> abc
1
2
3
4
2
3
4
因为匹配的是\w
,那么就要求是英文字符,后面跟了一个加号,意味着最少要有一个满足 \w
的字符才能够匹配到。如果text是一个空白字符或者是一个不满足\w
的字符,就会报错
text = ""
ret = re.match('\w+',text)
print(ret.group())
# >> AttributeError: 'NoneType' object has no attribute
1
2
3
4
2
3
4
# ?
:匹配的字符可以出现一次或者不出现(0或者1)
text = "123"
ret = re.match('\d?',text)
print(ret.group())
# >> 1
1
2
3
4
2
3
4
# {m}
:匹配m个字符
text = "123"
ret = re.match('\d{2}',text)
print(ret.group())
# >> 12
1
2
3
4
2
3
4
# {m,n}
:匹配 m-n 个字符,在这中间的字符都可以匹配到
text = "123"
ret = re.match('\d{1,2}',text)
prit(ret.group())
# >> 12
1
2
3
4
2
3
4
如果text只有一个字符,也可以匹配出来
text = "1"
ret = re.match('\d{1,2}',text)
prit(ret.group())
# >> 1
1
2
3
4
2
3
4
# 几个实际的案例(以给出的文本为例)
- 验证手机号码:手机号码的规则是以1开头,第二位可以是34587,后面那9位就可以随意了
text = "18570631587"
ret = re.match('1[34587]\d{9}',text)
print(ret.group())
# >> 18570631587
1
2
3
4
2
3
4
- 如果是个不满足条件的手机号码。那么就匹配不到了
text = "1857063158"
ret = re.match('1[34587]\d{9}',text)
print(ret.group())
# >> AttributeError: 'NoneType' object has no attribute
1
2
3
4
2
3
4
- 验证邮箱:邮箱的规则是邮箱名称是用数字、数字、下划线组成的,然后是@符号,后面就是域名了
text = "hynever@163.com"
ret = re.match('\w+@\w+\.[a-zA-Z\.]+',text)
print(ret.group())
1
2
3
2
3
- 验证URL:URL的规则是前面是http或者https或者是ftp然后再加上一个冒号,再加上一个斜杠,再后面就是可以出现任意非空白字符了
text = "http://www.baidu.com/"
ret = re.match('(http|https|ftp)://[^\s]+',text)
print(ret.group())
1
2
3
2
3
- 验证身份证:身份证的规则是,总共有18位,前面17位都是数字,后面一位可以是数字,也可以是小写的x,也可以是大写的X
text = "3113111890812323X"
ret = re.match('\d{17}[\dxX]',text)
print(ret.group())
1
2
3
2
3
# ^
:表示以...开始
text = "hello"
ret = re.match('^h',text)
print(ret.group())
1
2
3
2
3
如果是在中括号中,代表的是取反操作
# $
:表示以...结束
# 匹配163.com的邮箱
text = "xxx@163.com"
ret = re.search('\w+@163\.com$',text)
print(ret.group())
# >> xxx@163.com
1
2
3
4
5
2
3
4
5
# |
:匹配多个表达式或者字符串
text = "hello|world"
ret = re.search('hello',text)
print(ret.group())
# >> hello
1
2
3
4
2
3
4
# 贪婪模式和非贪婪模式
- 贪婪模式:正则表达式会匹配尽量多的字符,默认是贪婪模式。
- 非贪婪模式:正则表达式会尽量少的匹配字符。
text = "0123456"
ret = re.match('\d+',text)
print(ret.group())
# 因为默认采用贪婪模式,所以会输出0123456
1
2
3
4
2
3
4
可以改成非贪婪模式,就只会匹配到0
text = "0123456"
ret = re.match('\d+?',text)
print(ret.group())
1
2
3
2
3
# 匹配0-100之间的数字
text = '99'
ret = re.match('[1-9]?\d$|100$',text)
print(ret.group())
1
2
3
2
3
如果text=101,就会抛出一个异常
text = '101'
ret = re.match('[1-9]?\d$|100$',text)
print(ret.group())
# >> AttributeError: 'NoneType' object has no attribute 'group'
1
2
3
4
2
3
4
# 转义字符和原生字符
在正则表达式中,有些字符是有特殊意义的字符,在 Python 中 \
也是用来转义的,因此如果想要在普通的字符串中匹配 \
,那么就要给出 四个 \
text = "apple \c"
ret = re.search('\\\\c',text)
print(ret.group())
1
2
3
2
3
所以要使用原生字符就可以解决这个问题
text = "apple \c"
ret = re.search(r'\\c',text)
print(ret.group())
1
2
3
2
3
← BeautifulSoup库 re模块 →