1、re模块
1.1re模块的概念
re模块就其本质而言,正则表达式(或RE)是一种小型的、高度专业化的编程语言,它内嵌于python中,并通过re模块实现。正则表达式模式被编译成一系列的字节码,然后用c编写的匹配引警执行。
1.2 字符匹配
普通字符:大多数字符和字母都会和自身匹配。
import re >>> re.findall('czd','chenyzczdcqy') ['czd']
元字符:
. | 通配符,数字字母都可以匹配,除了“ ”以外,一个点代表一个字符 |
^ | 表示以...开头。在多行模式中匹配每一行的开头 |
$ | 表以...结尾 在多行模式中匹配每一行的末尾 |
* | 匹配前一个字符0或多次 |
+ | 匹配前一个字符1次或无限次 |
? | 匹配一个字符0次或1次 |
{} | {m}匹配前一个字符m次,{m,n}匹配前一个字符m至n次,若省略n,则匹配m至无限次 |
[] | 字符集。对应的位置可以是字符集中任意字符。字符集中的字符可以逐个列出,也可以给出范围,如[abc]或[a-c]。[^abc]表示取反,即非abc。 所有特殊字符在字符集中都失去其原有的特殊含义。用反斜杠转义恢复特殊字符的特殊含义。 |
() | 被括起来的表达式将作为分组,从表达式左边开始没遇到一个分组的左括号“(”,编号+1. 分组表达式作为一个整体,可以后接数量词。表达式中的|仅在该组中有效。 |
| | 或。匹配|左右表达式任意一个,从左到右匹配,如果|没有包括在()中,则它的范围是整个正则表达式 |
转义字符,使后一个字符改变原来的意思 |
注意:
a.反斜杠的作用
(1)去除元字符的特殊功能
(2)反斜杠后跟普通字符实现特殊功能
b. * + . ? 都是贪婪匹配,后面加?使其变为惰性匹配。
例如:
>>> ret=re.findall("abc*?",'abccccc') >>> print(ret) ['ab']
1.3 预定义字符集
d | 匹配任何数字, 它相当于类[0-9] |
D | 匹配任何字符, 它相当于类[ ^0-9] |
s | 匹配任何空白字符, 相当于类[ fv] |
S | 匹配任何非空白字符, 相当于类[^ fv] |
w | 匹配任何字母数字字符,相当于类[a-z A-Z 0-9] |
W | 匹配任何非字母数字字符,相当于类[^a-z A-Z 0-9] |
匹配一个特殊字符边界,如空格 & #等 |
注意的用法:
w = re.findall('tina','tian tinaaaa') print(w) s = re.findall(r'tina','tian tinaaaa') print(s) v = re.findall(r'tina','tian#tinaaaa') print(v) a = re.findall(r'tina','tian#tina@aaa') print(a) 执行结果如下: [] ['tina'] ['tina'] ['tina']
1.4 元字符之分组的一些特殊用法
(?P<name>) | 分组,除了原有的编号外再指定一个额外的别名 |
(?P=name) | 引用别名为<name>的分组匹配到字符串 |
<number> | 引用编号为<number>的分组匹配到字符串 |
1.5 re模块下的常用方法
import re # re.findall遍历匹配,可以获取字符串中所有匹配的字符串,返回一个列表。 ret=re.findall('alv','alvin dong') print(ret) #re.search 格式: # re.search(pattern, string, flags=0) # re.search函数会在字符串内查找模式匹配,只要找到第一个匹配然后返回,如果字符串没有匹配,则返回None。 # print(re.search('dcom','www.4comrunoob.5com').group()) # 执行结果如下: # 4com # 注:match和search一旦匹配成功,就是一个match object对象,而match object对象有以下方法: # •group() 返回被 RE 匹配的字符串 # •start() 返回匹配开始的位置 # •end() 返回匹配结束的位置 # •span() 返回一个元组包含匹配 (开始,结束) 的位置 # •group() 返回re整体匹配的字符串,可以一次输入多个组号,对应组号匹配的字符串。 # # a. group()返回re整体匹配的字符串, # b. group (n,m) 返回组号为n,m所匹配的字符串,如果组号不存在,则返回indexError异常 # c.groups()groups() 方法返回一个包含正则表达式中所有小组字符串的元组,从 1 到所含的小组号,通常groups()不需要参数, # 返回一个元组,元组中的元就是正则表达式中定义的组。 a = "123abc456" print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(0)) #123abc456,返回整体 print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(1)) #123 print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(2)) #abc print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(3)) #456 ###group(1) 列出第一个括号匹配部分,group(2) 列出第二个括号匹配部分,group(3) 列出第三个括号匹配部分。
# re.match # 决定RE是否在字符串刚开始的位置匹配。//注:这个方法并不是完全匹配。当pattern结束时若string还有剩余字符,仍然视为成功。 # 想要完全匹配,可以在表达式末尾加上边界匹配符'$' ret=re.match('a','abcd').group() print(ret) # a # re.split ret=re.split('[ab]','abcd') #先按'a'分割得到' '和'bcd',再对' '和'bcd'按'b'分割 print(ret) #['', '', 'cd'] # re.sub # 使用re替换string中每一个匹配的子串后返回替换后的字符串。 ret=re.sub('d','abc','czd5cyz6',1) print(ret) #czdabccyz6 ret=re.subn('d','abc','czd5cyz6') print(ret) #('czdabccyzabc', 2) # re.compile # 编译正则表达式模式,返回一个对象的模式。 # (可以把那些常用的正则表达式编译成正则表达式对象,这样可以提高一点效率.) obj=re.compile('d{3}') ret=obj.search('abc123eee') print(ret) #<re.Match object; span=(3, 6), match='123'> print(ret.group()) #123 # finditer # 搜索string,返回一个顺序访问每一个匹配结果(Match对象)的迭代器。 # 找到 RE 匹配的所有子串,并把它们作为一个迭代器返回。 ret=re.finditer('d','asdcva123rage56a') #存放到迭代器 print(ret) #<callable_iterator object at 0x0000029435077668> print(next(ret).group()) #1 print(next(ret).group()) #2
# 注意 import re ret=re.findall('www.(baidu|fzuniv).com','www.fzuniv.edu') print(ret) #[] # 这是因为分组后,findall首先拿出分组里面的内容,要想匹配结果,取消权限即可 ret=re.findall('www.(?:baidu|fzuniv).edu','www.fzuniv.edu') print(ret) #['www.fzuniv.edu']
2、logging模块
import logging logging.debug('debug message') logging.info('info message') logging.warning('warning message') logging.error('error message') logging.critical('critical message') # 执行的结果: WARNING:root:warning message ERROR:root:error message CRITICAL:root:critical message
可见,默认情况下python的logging模块将日志打印到了标准输出中,且只显示了大于等于WARNING级别的日志,这说明默认的日志级别设置为WARNING(日志级别等级:CRITICAL>ERROR>WARNING>INFO>DEBUG>NOTEST),默认的日志格式为:日志级别:logging名称:用户输出信息。
2.1 logging.basicConfig
import logging logging.basicConfig( level=logging.DEBUG, filename='logger.logger', filemode='w', format='%(asctime)s [%(lineno)s] %(filename)s %(message)s' ) logging.debug('debug message') logging.info('info message') logging.warning('warning message') logging.error('error message') logging.critical('critical message') # logging对象 logger=logging.getLogger() logger.setLevel('DEBUG') fh=logging.FileHandler('test_log') ch=logging.StreamHandler('test_log') fm=logging.Formatter('%(asctime)s %(message)s') fh.setFormatter(fm) ch.setFormatter(fm) logger.addHandler(fh) logger.addHandler(fh) logger.debug('writen debug message') logger.info('writen info message') logger.warning('writen warning message') logger.error('writen error message') logger.critical('writen critical message')
在logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有:
(1)filename:用指定的文件名创建FiledHandler,这样日志会被存在指定的文件中
(2)filemode:文件打开方式,在指定了filename时使用这个参数。默认值为'a'还可指定为'w'
(3)format:指定handler使用的日志显示格式
(4)datefmt:指定日期时间格式
(5)level:设置rootlogger的日志级别
(6)stream:用指定的stream创建StreamHandler,可以指定输出到sys.stdeer、sys.stdout或者文件
f=open('test.log','w')默认为sys.stdeer。若同时列出filename和stream两个参数,则stream参数会被会略。
format参数中可能用到的格式化串
(1) %(name)s logger的名字
(2) %(levelno)s 数字形式的日志级别
(3) %(levelname)s 文本形式的日志级别
(4) %(pathname)s 调用日志输出函数的模块的完整路径名
(5) %(filename)s 调用日志输出函数的模块的文件名
(6) %(module)s 调用日志输出函数的模块名
(7) %(funcName)s 调用日志输出函数的函数名
(8) %(lineno)d 调用日志输出函数语句所在的代码行
(9) %(created)f 当前时间,用UNIX标准的表示时间的浮点数
(10) %(relativeCreated)s 输出日志信息时的,自logger创建以来的毫秒数
(11) %(asctime)s 字符串形式的当前时间,默认格式是“2003-07-19 17:27:43,789”,逗号后面是毫秒数
(12) %(message)s 用户输出的信息
(13) %(process)d 进程ID,可能没有