"""
re模块与正则表达式之间的关系
    正则表达式不是python独有的 而它是一门独立的技术在任何语言中都可以见到它只不过运用的的方法不一样
    所有的编程语言都可以使用正则
    但是你如果想在python中使用 那么你就要依赖与re模块
    
    
正则的介绍
    正则就是用来筛选字符串中特定的内容
    一个正则就可以写成一本书所以可见这正则是有多么的千变万化
    书名:正则指引
     正则的应用场景
        1.爬虫
        2.数据分析
在python中只要是reg .....开头的东西一般情况下都是和正则有关系的

1 想匹配具体内容 可以直接写完整的内容,不需要写正则

字符组[]
    一个字符串里面的表达式都是或的关系
    
^与$符连用会精准的限制匹配的内容
两者之间写什么 那么匹配的字符就必须是什么
多一个不行少一个也不行

adc|ad  一定要将长的放在最前面
^ 直接写在外面的 限制字符串的开头
[^] 除了[]写的字符不要其他的都要  



正则匹配的时候默认都是贪婪匹配(尽量匹配的多)
在这个时候你可以通过在量词后面加一个?号就可以将贪婪匹配编程非贪婪匹配(就是尽量的往少了匹配)

量词必须跟在正则负号后面
量词只能能够限制挨着他的那个正则负号

分组: 当多个正则负符号需要重复多次的时候或者当做一个一个整体进行其他的操作,那么可以分组形式
        分组在正则中的语法就是()括号
        
        
        
 python 中使用正则必须借助于re模块 或者是支持正则表达书写方式
 import re
 re模块中常用的三种方式
 findall
 search
 match
 ----------------
 三种模式的使用以及介绍使用的方式
 1.findall
     res = re.findall(res = re.findall('[a-z]+','eva egon jason')
     findall('正则表达式','带匹配的字符串')
     print(res)
     找出字符串中符合正则表达式全部内容 并且返回的是一个列表,列表中的元素就是正则匹配到的结果

 2search
 res = re.search('a','eva egon jason')
     print(res)  # search不会给你直接返回匹配到的结果 而是给你返回一个对象
     print(res.group())  # 必须调用group才能看到匹配到的结果

注意:
    1.search只会依据正则拆一次只要查到结果了 就不会再往后查找了
    2.当查找的结果不存在的情况年 调用group直接回报错
    
    下面这样的表达方式不会出错 如果调用没有的话group()回返回None
    res = re.search("a","eva egon jason")
    #格式search("正则表达式","带匹配的字符串")
    if res:
        print(res.group())
  
  3.match
        1.match只会匹配字符串开头到的部分
        2.当字符串不符合匹配的情况下返回的也是None 调用group也会报错
        res = re.match('a','eva egon jason')
        print(res)
        print(res.group()) 
    
不常用的re内置方法
   
1.split
ret = re.split('[ab]', 'abcd')  # 先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割
print(ret)  # ['', '', 'cd'] 返回的还是列表

2.sub
 ret = re.sub('\d', 'H', 'eva3egon4yuan4',1)  # 将数字替换成'H',参数1表示只替换1个
 sub('正则表达式','新的内容','待替换的字符串',n)
 
 先按照正则表达式查找所有符合该表达式的内容 统一替换成'新的内容'  还可以通过n来控制替换的个数
 
 print(ret)  # evaHegon4yuan4
3.subn
 ret = re.subn('\d', 'H', 'eva3egon4yuan4')  # 将数字替换成'H',返回元组(替换的结果,替换了多少次)
 ret1 = re.subn('\d', 'H', 'eva3egon4yuan4',1)  # 将数字替换成'H',返回元组(替换的结果,替换了多少次)
 print(ret)  # 返回的是一个元组 元组的第二个元素代表的是替换的个数
4.compile
 obj = re.compile('\d{3}')  #将正则表达式编译成为一个 正则表达式对象,规则要匹配的是3个数字
 ret = obj.search('abc123eeee') #正则表达式对象调用search,参数为待匹配的字符串
 res1 = obj.findall('347982734729349827384')
 print(ret.group())  #结果 : 123
 print(res1)  #结果 : ['347', '982', '734', '729', '349', '827', '384']


 import re
 5.finditer                            
 ret = re.finditer('\d', 'ds3sy4784a')   #finditer返回一个存放匹配结果的迭代器
 print(ret)  # <callable_iterator object at 0x10195f940>
 print(next(ret).group())  # 等价于ret.__next__()
 print(next(ret).group())  # 等价于ret.__next__()
 print(next(ret).group())  # 等价于ret.__next__()
 print(next(ret).group())  # 等价于ret.__next__()
 print(next(ret).group())  # 等价于ret.__next__()
 print(next(ret).group())  # 等价于ret.__next__()   查出迭代取值的范围 直接报错
 print(next(ret).group())  #查看第一个结果
 print(next(ret).group())  #查看第二个结果
 print([i.group() for i in ret])  #查看剩余的左右结果


import re
# res = re.search('^[1-9](\d{14})(\d{2}[0-9x])?$','110105199812067023')
# 还可以给某一个正则表达式起别名
# res = re.search('^[1-9](?P<password>\d{14})(?P<username>\d{2}[0-9x])?$','110105199812067023')
# print(res.group())
# print(res.group('password'))
# print(res.group(1))
# print(res.group('username'))
# print(res.group(2))
# print(res.group(2))
# print(res.group(1))