#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
通配符:
. 匹配除换行符之外的任意一个字符
* 匹配前一个字符0或多次
.*就是匹配任意字符0到多次(默认匹配最长的字符串)
+ 匹配前一个字符1或多次
.+就是匹配任意字符1到多次(默认匹配最长的字符串)
? 匹配前一个字符0或1次
.?就是匹配任意字符0或1次(默认匹配最长的字符串)
^ 以xxx开头
$ 以结尾
{m} 匹配前一个字符m次
{m,n} 匹配前一个字符m到n次(m可省略,默认为0,即0到n次)
[] 匹配[]中列出的任意一个字符。如:a[bc]d,匹配:abd、acd 还可以这样写[a-z,A-Z,1-9]:匹配任意一个字母(大小写)或数字
| 代表表达式左右任意匹配一个。如abc|abd:匹配abc或abd
() 分组,已经匹配到的结果里再对分组的内容进行匹配。括号内的内容作为一个整体进行匹配操作。如:(abc){2}---对括号内的内容匹配2次,即匹配结果为:abcabc
\ 转义,将具有特殊意义的通配符变成其原来的符号,使其不再具有特殊意义
\d 匹配数字
\D 匹配非数字
\s 匹配空白字符(\r\n\\t等)
\S 匹配非空白字符
\w 匹配单词字符 [a-z,A-Z,1-9_]
\W 匹配非单词字符[^\w]
\b 匹配一个单词边界,只能匹配单词的词首或词尾 如:\bh 匹配以h开头的单词词首;h\b 匹配以h结尾的单词词尾
'''
import re
'''
s = 'hahaalexissbyoualsoissxbandalexwugassxldxufualex'
result = re.findall('alex',s) #将字符串s中所有匹配‘alex’的都找出来
print(result)
print(re.findall('al.x',s))
print(re.findall('^alex',s)) #查找以alex开头的字符(在起始位置匹配‘alex’)
print(re.findall('alex$',s)) #查找以alex结尾的字符(在结尾位置匹配‘alex’)
print(re.findall('al.*x','sdfalxasdfwe')) #*是匹配前一个字符0或多次,.*就是匹配任意字符0到多次(默认匹配最长的字符串)
print(re.findall('al.+x','sdfalxasdfwe')) #+是匹配前一个字符1或多次,.+就是匹配任意字符1到多次(默认匹配最长的字符串)
print(re.findall('al.?x','sdfalsdxasdfwe')) #?是匹配前一个字符0或1次,.?就是匹配任意字符0到1次(默认匹配最长的字符串)
print(re.findall('ab{3}c','abbcabbbc')) #匹配3次b即最后匹配的字符串时abbbc
print(re.findall('ab{,3}c','abbcabbbc')) #匹配0到3次b即最后匹配的字符串时abbc、abbbc
print(re.findall('a[bc]d','abdabcdacd'))
print(re.findall('a[0-9,a-z]c','adca1caaaa'))
print(re.findall(r'\bm.*','hello,my name is amt')) #匹配以m开头的单词的词首
'''
'''
#re常用方法
result = re.match(r'com','comsdfsdfcom') #match只匹配字符串的起始位置,其他位置不匹配
print(result.group()) #match生成的是一个对象,要想获取匹配结果,需要使用group方法
result1 = re.search(r'com','cosdfcomsdfcom') #search只匹配字符串中找到的第一个位置,后面的就不再匹配
print(result1.group()) #获取匹配结果
print(result1.span()) #获取匹配的位置(开始到结束的下标)
print(result1.start()) #获取匹配的首位置(开始的下标)
result2 = re.findall('com','cosdfcomsdfcom') #匹配字符串中所有匹配的结果
print(result2) #findall返回的是一个列表
result3 = re.finditer('com','cosdfcomsdfcom') #功能上和findall相同,区别是其返回的结果是一个迭代器,需要遍历输出
print(result3)
for i in result3:
print(i.span()) #i.group()、i.start()
result = re.sub('g.t','have','I get A,I got B,I gut C') #匹配替换,所有符合匹配规则的对象,都替换成’have‘
#result = re.sub('g.t','have','I get A,I got B,I gut C',2) #匹配替换,所有符合匹配规则的对象,都替换成’have‘,最大替换2次
#sub参数:1匹配规则、2要替换的字符串、3要匹配的字符串、4最大替换次数(默认全部替换)
print(result)
result1 = re.subn('g.t','have','I get A,I got B,I gut C') #功能与sub相同,区别是返回结果不仅返回了替换后的字符串,还返回了替换次数
print(result1)
result = re.split('\d+','one1two2three3four') #分割字符串。以一个或多个十进制数来分割字符串
print(result) #返回的结果里没有分割的字符
result1 = re.split('(\d+)','one1two2three3four') #分割字符串。规则里加了分组
print(result1) #返回的结果里除了正常匹配来的结果,还包含了分组的结果
#前面的方法执行时都是两个过程一起进行的,如果针对同一个规则来操作不同的字符串,要是每次执行都进行一次编译就会浪费时间,
# 因此可以先对规则进行编译,以后再用此规则对字符串进行操作时就省去了编译的时间,效率就提高了
r = re.compile(r'com') #先对匹配规则进行编译
result = r.findall('comasdfcomsdfa') #用编译好的规则操作字符串
print(result)
'''
#对于转义,正则表达式使用转义时,由于python自身也有转义功能,因此python解释器就会将正则表达式中定义的转义再进行一次转义,
# 这样结果就不再准确了。为了解决这一问题,python使用re模块定义正则表达式规则时,在规则前加上r,这样就代表这是一个正则表达式,
#python解释器就不会再进行第二次转义了。
print(re.search(r'\\com','s\com').group()) #匹配'\com'字符串(前面一定要加r,不然就匹配不到'\')
result = re.search('h(\w+)','I have a book')
print(result.group()) #group返回正常匹配结果(分组对group的结果没有影响)
print(result.groups()) #groups返回分组的结果
result1 = re.search('h(?P<name>\w+)','I have a book') #?P<name>:为分组取名为name
print(result1.group()) #group返回正常匹配结果(分组对结果没有影响)
print(result1.groups()) #groups返回分组的结果
print(result1.groupdict()) #groupdict返回分组的结果(以字典形式)----该方法只有在分组取名的情况下才能有值
#对于findall()方法,如果规则里有分组,虽然仍然是以一个整体去进行匹配的,但返回结果时就只获取分组的匹配结果
#result2 = re.findall('h(\w+)','I have a book')
result2 = re.findall('h\w+','I have a book')
print(result2)