2018-09-11 Day17 正则表达式

01.正则表达式

正则表达式就是用来检测字符串是否满足某种规则的工具
例如:1.账号是手机号/邮箱/多少位由什么东西组成等.....
         2.脏话替换成*等.....

1.正则语法
2.python对正则表达式的支持,提供了一个内置模块:re
fullmatch(正则表达式,字符串):判断字符串是否符合正则表达式规则

1) . 匹配任意字符
匹配一个字符串,只有一位字符并且这个字符是任意字符=========================1.单个字符========================

from re import fullmatch,search,findall
re_str = r'.'
result=fullmatch(re_str,'a')
print(result)

# 匹配一个字符串,只有两位字符并且每个字符是任意字符
re_str = r'..'
result=fullmatch(re_str,'an')
print(result)

# 匹配一个字符串,前三位分别是abc,最后一位是任意字符
re_str = r'abc.'
result = fullmatch(re_str,'abc%')
print(result)

2) \w 匹配字母数字下划线
匹配一个字符串,前三位分别是abc,最后一位是字母数字或者下划线

re_str = r'abc\w'
result = fullmatch(re_str,'abc1')
print(result)

3) \s 匹配空白字符
(空白指空格、制表符和回车等所有能产生空白的字符)匹配一个字符串,前三位是字母数字下划线第四位是一个空白符最后一位是匹配任意字符

re_str = r'\w\w\w\s.'
result = fullmatch(re_str,'bHz\n.')
print(result)

4)\d 匹配一个数字字符
匹配一个字符串,前三位是数字字符,最后一位是任意字符

re_str = r'\d\d\d.'
result = fullmatch(re_str,'979L')
print(result)

5)\b 检测是否为单词边界
(单词的开头,单词的结尾,单词和单词之间的标点空格等)匹配一个字符串是前三位是ftR,第四位是空白,空白后边是fRFTR。并且第三位R后面是个单词边界
注意:正则中遇到\b,匹配的时候先不管它,匹配成功后再回头看\b位置是否是单词边界

re_str = r'ftR\b\sfRFTR'
result = fullmatch(re_str,'ftR fRFTR')
print(result)

6)^检测字符串是否以给定的正则表达式开头
匹配一个字符串,是否以两个数字字符开头

re_str = r'^\d\d'
result = fullmatch(re_str,'99')
print(result)
result = search(r'^\d\d','99aaa')
print(result)

7) $检测字符串是否以给定的正则表达式结束
匹配一个字符串a数字,并且a数字是字符串的结尾

re_str = r'a\d$'
result = fullmatch(re_str,'a8')
print(result)

result = search(re_str,'a9aaa9')
print(result)

8) \W 匹配一个非数字、字母、下划线的字符

re_str = r'\W\w'
result = fullmatch(re_str,'!a')
print(result)

9) \S 匹配非空白字符

re_str = r'\S\s\w'
result = fullmatch(re_str,'F _')
print(result)

10) \D 匹配非数字的字符
11)\B 检测非单词边界

# re_str = r'\b\B'
# result = fullmatch()

=========================2.匹配次==========================
1)[] 匹配中括号中出现的任意字符
注意: 一个中括号只匹配一个字符
匹配一个3位的字符串,第一位是a或者b或者c,后两位是数字

re_str = r'[abc+]\d\d'
result = fullmatch(re_str,'+99')
print(result)

-(减号)在正则中的中括号中的应用:如果将减号放到两个字符的中间代表的谁到谁,如果想要表示‘-’符号本身,就放在开头或者结尾。
  要求一个字符串中的第一个是1-8中的一个,后面两位是小写字母。[1-8]:代表的字符集是:12345678。[-18]或者[18-]:代表的字符集是'1','8','-'要求写一个字符串中的第一个是1-8的一个数,后面两位是小写字母

re_str = r'[1-9][1-9][1-9][1-9][a-z][a-z][a-z]'
result = fullmatch(re_str,'9799lhy')
print(result)

2) [^字符集] 匹配不在[]字符集中的任意一个字符
匹配一个四位的字符串,第一位不是大写字母也不是数字,后三位是abc

re_str = r'[^A-Z\d]abc'
result = fullmatch(re_str,'了abc')
print(result)

3) *匹配0次或者多次
匹配一个字符串,最后一位是b,b的前面有0个或者多个a

re_str = r'a*b' #'b','ab','aab','aaab'......
print(fullmatch(re_str,'aaab'))

4) + 匹配1次或者多次(至少一次)
判断一个字符串是否是无符号的整数

re_str = r'[1-9]+\d*'
print(fullmatch(re_str,'1010'))

5)?匹配0次或者一次

re_str = r'@?\d+'
print(fullmatch(re_str,'@9799'))

练习:判断一个字符串是否是整数(包含正整数和负整数)
+200 -100 99,-1

re_str = r'[+-]?\d*'
print(fullmatch(re_str,'-1'))

6){N} 匹配N次

re1_str = r'\d{3}'  #匹配3位数字字符串
re_str = r'[a-zA-Z]{3}'  #匹配3位字母字符串
print(fullmatch(re_str,'ftr'))

7){N,}至少匹配N次

re_str = r'\w{4,}'
print(fullmatch(re_str,'ftr_2027'))

8) {,N}最多匹配N次

re_str = r'a{,4}b' #'b','ab','aab','aaab','aaaab'
print(fullmatch(re_str,'b'))

注意:次数相关的操作,都是约束的次数符号前的前一个字符

9){M,N}匹配至少M次,最多N次 (N>M)

re_str = r'a{2,5}b' #'aab','aaab','aaaab','aaaaab'
print(fullmatch(re_str,'aaaaab'))

========================3.分之和分组=======================
1)|分之(相当于逻辑运算中的or)
匹配一个字符串是三个字母或者是三个数字

re_str = r'[a-zA-Z]{3}|\d{3}|\dabc'
print(fullmatch(re_str,'1abc'))``` 
# \d{3}[a-z]{2}是分之中的第一个条件,[A-F]{3}分之的第二个条件
re_str = r'\d{3}[a-z]{2}|[A-F]{3}'
print(fullmatch(re_str,'123ab'))
print(fullmatch(re_str,'ABC'))

注意:正则中的分之有短路操作:如果使用|去连接多个条件,前面的条件已经匹配出结果,那么就不会使用后面的条件再去匹配
练习:写一个正则表达式,能够匹配出字符串中所有的数字(包括整数和小数)
'abc12.5hhh60,30.2kkk9nn0.12'

re_str = r'[1-9]\d*[.]?\d*|0[.]\d+'
print(findall(re_str,'abc12.5hhh60,30.2kkk9nn0.12'))

2)分组
通过加()来对正则条件进行分组
两位数字两位字母出现3次

re_str = r'([a-z]{2}\d{2}){3}'
print(fullmatch(re_str,'aa23bb34cc45'))
re_str = r'([a-z]{2}\d{2})'
print(findall(re_str,'aa23bb34cc45'))

# 匹配一个字符串,按照一个数字一个字母的规律出现一次或多次
re_str = r'(\d[a-z])+'
print(fullmatch(re_str,'9a2s3k5f8g0f'))

b.重复
可以通过\数字来重复匹配前面的分组中匹配的结果。数字的值代表前面的第几个分组

re_str = r'(\d{2}[A-Z])=%\1\1'
print(fullmatch(re_str,'23B=%23B23B'))

re_str = r'(\d{3})-(\w{2})\1\2'
print(fullmatch(re_str,'123-ab123ab'))

c.捕获
按照完整的正则表达式去匹配,只捕获()中的内容。只有在findall中有效

re_str = r'a(\d{3})b'
print(fullmatch(re_str,'a786b'))
print(findall(re_str,'a786b'))

02.正则中的转义

1.正则表达式中的转义和字符串中的转义字符没有任何关系。
在python中的字符串前加r阻止的是字符串转义,不是阻止正则表达式转义。

2.在正则表达式中,可以通过有特殊意义的符号前加‘\’来表示符号本身
+ . * ? \ ( ) [ ] ^ $ |
注意:
a. - 只有在中括号中的两个字符之间才有特殊的意义
b. 如果特殊符号放到[]中作为字符集的内容,那么除了-在两个字符之间以外其他的都不需要转义外,
c. \不管在哪都需转义,^放在中括号的最前面需要转义

import re
from re import fullmatch

re_str = r'a\+'
print(re.fullmatch(re_str,'a+'))

re_str = '\+a'
print(re.fullmatch(re_str,'+a'))

re_str = r'\\w-a'
print(re.fullmatch(re_str,'\w-a'))

re_str = r'\(\d{3}'
print(re.fullmatch(re_str,'(123'))

re_str = r'[.?*\\]mbc\\'
print(re.fullmatch(re_str,'\mbc\\'))

03.re模块

import re
1.compile(正则表达式):将正则表达式转换成正则表达式对象

re_str = r'\d+'
re_object = re.compile(re_str)
print(re_object)

# 不转成对象,调用相应的函数
re.fullmatch(re_str, '89z')
# 转换成对象,调用相应的方法
re_object.fullmatch('89d')

2.match(正则表达式,字符串) 和 fullmatch(正则表达式,字符串)
  a.match:判断字符串的开头是否能够和正则表达式匹配
  b.fullmatch:判断整个字符串是否能够和正则表达式匹配
  c.返回值都是匹配结果,如果匹配成功返回匹配对象,否则返回None

re_str = 'abc\d{3}'
print(re.match(re_str, 'abc456'))
print(re.fullmatch(re_str, 'abc456'))
match2 = re.fullmatch(re_str, 'abc456')

a.匹配到的范围,匹配结果字符的下标范围:(起始下标,结束下标)---结束下标取不到

print(re.fullmatch(re_str, 'abc456').span())
# 获取起点
print(re.fullmatch(re_str, 'abc456').start())
# 获取终点
print(re.fullmatch(re_str, 'abc456').end())

# 注意:group参数,用来指定分组对应的相应的结果
re_str = r'(\d{3})\+([a-z]{2})'
match1 = re.match(re_str, '567+hj')
print(match1)
print(match1.span())
# 在匹配结果中,获取第1个分组的范围
print(match1.span(1))
# 在匹配结果中,获取第2个分组的范围
print(match1.span(2))
# 在匹配结果中,获取第2个分组的起始下标
print(match1.start(2))

b.获取匹配结果对应的字符串

print(match1.group())
print(match1.group(1))
print(match1.group(2))

c.获取被匹配的原字符串
print(match1.string)

3.search(正则表达式,字符串):
在字符串中去查找第一个满足正则表达式要求的子串,如果找到就返回匹配对象,找不到返回None

search1 = re.search(r'\d+aa', '9aahello 99aa world')
print(search1)
if search1:
    print(search1.span())

练习:使用search将一个字符串中所有的数字字符串全部找到

str1 = '工资是10000元,年龄是18岁,升高是180,颜值100'
re_str = r'[1-9]\d+'
search2 = re.search(re_str, str1)
while search2:
    print(search2.group())
    end = search2.end()
    str1 = str1[end:]
    search2 = re.search(re_str, str1)
``python
**4.split(正则表达式,字符串)**
**a.**按满足正则表达式的子串去切割字符串
**b.**返回值是列表
**c.**中文属于\W范围
```python
str1 = '地方,都是。双方各,而!'
result = re.split(r'[\W+]', str1)
print(result)

5.sub(正则表达式,替换字符串,被替换的字符串)

word = '傻叉!!操你大爷!Fuck you 煞笔'
result = re.sub(r'傻叉|操|Fuck|煞笔', '*', word)
print(result)

6.findall(正则表达式,字符串)
a.获取字符串中所有满足正则表达式的子串
b.返回值是列表
注意:分组中的捕获效果放在这儿有效

result = re.findall(r'\d([a-z]+)', '0hello是的范德萨0man,are you 0ok?合适的')
print(result)

你可能感兴趣的:(2018-09-11 Day17 正则表达式)