re模块的复习使用
re 正则基本使用
# re 正则
import re
# \w与\W
print(re.findall('\w', 'hello 123')) # \w 匹配数字 字母及下划线 ['h', 'e', 'l', 'l', 'o', '1', '2', '3']
print(re.findall('\W', 'hello 123###')) # \w 匹配 非 数字 字母及下划线 [' ', '#', '#', '#'] 匹配到了空格和#
# \s与\S
print(re.findall('\s', 'hello 123 sss')) # 匹配任意空字符 [' ', ' '] 匹配到了空格
print(re.findall('\S', 'hello 123 sss')) # ['h', 'e', 'l', 'l', 'o', '1', '2', '3', 's', 's', 's']
print(re.findall('\s', 'hello\t 123 sss \n')) # ['\t', ' ', ' ', ' ', '\n']
print(re.findall(r'\n', 'hello\t 123 sss \n')) # ['\n']
print(re.findall('\d', 'hello 123 sss')) # ['1', '2', '3'] 匹配数字
# \A \Z ^ $
print(re.findall('\Ahe', 'hello 123 sss')) # 匹配开头 ==^
print(re.findall('^he', 'hello 123 sss')) # 匹配开头
print(re.findall('sss\Z', 'hello 123 sss')) # 匹配结尾 ==$
print(re.findall('sss$', 'hello 123 sss')) # 匹配结尾 ==$
# 重复匹配 | . | * | ? | .* | .*? | + | {n,m} |
# * 匹配0个或者多个表达式
# + 匹配1个或者多个表达式
# ? 匹配0个或者1个由前面表达式定义的片段 非贪婪方式
print(re.findall('a.b', 'axb')) # d点匹配一个
print(re.findall('a.b', 'a1b a*b a b aaab')) # ['a1b', 'a*b', 'a b', 'aab']
print(re.findall('a*b', 'abbbbcccccc')) # ['ab', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b']
print(re.findall('ab*', 'abbbbbbbbbbbb')) # ['abbbbbbbbbbbb'] 匹配到多个b
print(re.findall('ab*', 'bbbbbbbbbbbb')) # [] 匹配到0个b
# ?
print(re.findall('ab?', 'a')) # 匹配0个或者1个由前面正则表达式定义的片段 ['a']
print(re.findall('ab?','abbb')) # ['ab']
# 匹配所有的数字 小数
print(re.findall('\d+\.?\d*','asdfasdf123as1.13dfa12adsf1asdf3')) # +匹配一个或者多个 *匹配0个或者多个表达式
# .* 默认是贪婪匹配
print(re.findall('a.*b', 'axbbbbasdf')) # ['axbbbb'] 点是任意字符,通过*匹配任意的内容
# .*?默认是非贪婪匹配 推荐使用
print(re.findall('a.*?b', 'axxxbbbbasdf')) # ['axxxb']
# +
print(re.findall('ab+','abbbb')) # ['abbbb']
print(re.findall('ab+','a')) # []
# {n,m} 匹配n到m次由前面正则表达式定义的片段,贪婪方式
# {n} 精确匹配前面n个表达式
print(re.findall('ab{3}','abbb')) # 精确匹配前面3个 ['abbb']
print(re.findall('ab{2,4}','abbbbbbbb')) # ['abbbb']
print(re.findall('ab{1,}','abbb')) # == ab+
print(re.findall('ab{0,}','abbb')) # == ab*
# [] 用来表示一组字符 单独列出
print(re.findall('a[1*-]b','a1b a*b a-b')) # ['a1b', 'a*b', 'a-b']
print(re.findall('a[^1*-]b','a1b a*b a-b a=b')) # 取反['a=b']
print(re.findall('a[0-9]b','a1b a*b a-b a=b')) # ['a1b']
print(re.findall('a[a-z]b','a1b a*b a-b a=b acb')) # ['acb']
print(re.findall('a[a-zA-Z]b','a1b a*b a-b a=b acb aEb')) # ['acb', 'aEb']
# print(re.findall('a\\c','a\c')) # 这样转义会抛出异常 raise source.error("bad escape %s" % escape, len(escape))
print(re.findall(r'a\\c','a\c')) # r代表告诉解释器使用rawstring,即原生字符串,把我们正则内的所有符号都当普通字符处理,不要转义
print(re.findall('a\\\\c','a\c')) # 同上
# () 分组 匹配括号内的表示式,也表示一个组,()是匹配组内的内容
print(re.findall('ab+','ababab123')) # ['ab', 'ab', 'ab']
print(re.findall('(ab)+123','ababab123')) # ['ab'] 匹配到末尾ab123中的ab ???
print(re.findall('(?:ab)+123','ababab123')) # ['ababab123'] 让组内的内容全部匹配
# |
print(re.findall('compan(?:y|ies)','Too many companies have gone bankrupt, and the next one is my company'))
# ===================================================re 的其他介绍 ==================================================
print(re.findall('e','hello love eeee')) # 返回所有满足匹配条件的结果,放在列表里
print(re.search('e','hello love eeee').group()) # 找到第一个匹配然后返回该匹配信息的对象,通过gruop获取字符串,没有返回None
print(re.match('e','hello love eeee')) # None
print(re.match('e','ehello love eeee').group()) # e 是在字符串开始处匹配 完全可以用search+^代替match
print(re.split('[ab]','abcd')) # ['', '', 'cd'] 先按照a进行分割 分成'' 和bcd 然后按照b进行分割
print(re.sub('e','E','hello love eeee')) # hEllo lovE EEEE 不指定 替换所有
print(re.sub('e','E','hello love eeee',2)) # 指定参数 替换2次 hEllo lovE eeee
print(re.sub('e','E','hello love eeee',4)) # 指定参数 替换4次 hEllo lovE EEee
print(re.sub('^(\w+)(.*?\s)(\w+)(.*?\s)(\w+)(.*?)$',r'\6\4\3\2\1\5','hello love eeee ')) # 字符 空格 按照顺序进行排列
# 1 2 3 4 5 6
obj = re.compile('\d{2}')
print(obj.search('asdf733dasf').group()) # 73
print(obj.findall('asdf733dasf')) # ['73'] 重用了obj
# 匹配标签
print(re.findall("<(?P<tag_name>\w+)>\w+</(?P=tag_name)>","<script>hello</script>")) # ['script']
print(re.findall("<(?P<tag_name>\w+)>\w+</(?P=tag_name)>","<h1>hello</h1>")) # ['h1']
print(re.search("<(?P<tag_name>\w+)>\w+</(?P=tag_name)>","<h1>hello</h1>").group()) # 通过group显示查到的标签 <h1>hello</h1>
print(re.search("<(?P<tag_name>\w+)>\w+</(?P=tag_name)>","<h1>hello</h1>").groupdict()) # 把标签转换成字典格式{'tag_name': 'h1'}
print(re.search(r"<(\w+)>\w+</(\w+)>","<h1>hello</h1>").group()) # 同样获取标签内容
print(re.search(r"<(\w+)>\w+</\1>","<h1>hello</h1>").group())
正则实践应用
贪婪匹配和非贪婪匹配
Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能多的字符;非贪婪则相反,总是尝试匹配尽可能少的字符。在贪婪匹配后面加上?,使贪婪变成非贪婪。
- 贪婪匹配:* + {n,m} *.
- 非贪婪匹配:? .*?
···py
网上看到的例子 优点不是太理解 http://blog.csdn.net/real_ray/article/details/17502587
import re
s="This is a number 234-235-22-423"
r1=re.match(".+?(\d+-\d+-\d+-\d+)",s) # 加了问好变成非贪婪匹配 234-235-22-423
r2=re.match(".+(\d+-\d+-\d+-\d+)",s) # 4-235-22-423
print(r1.group(1))
print(r2.group(1))
print(re.search('(\d+-\d+-\d+-\d+)',s).group()) # 用search更好理解
···
正则表达式模式中使用到通配字,那它在从左到右的顺序求值时,会尽量“抓取”满足匹配最长字符串,在我们上面的例子里面,“.+”会从字符 串的启始处抓取满足模式的最长字符,其中包括我们想得到的第一个整型字段的中的大部分,“\d+”只需一位字符就可以匹配,所以它匹配了数字“4”,而“.+”则匹配了从字符串起始到这个第一位数字4之前的所有字符。
解决方式:非贪婪操作符“?”,这个操作符可以用在"*","+","?"的后面,要求正则匹配的越少越好。
参考:
http://www.cnblogs.com/linhaifeng/articles/6384466.html#_label13