python之re和logging模块

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,可能没有

原文地址:https://www.cnblogs.com/changzhendong/p/11249650.html