刘总的笔记小站

生活常识,娱乐搞笑,编程技巧,智能家居,深度学习,网络神经,数据挖掘

python语法和正则表达式及编解码

python常用语法比较简单,变量声明,条件判断,循环遍历,深点有面向对象,装饰器。

一些常用的数据结构和知识总结,梳理如下:


一,python基本的数据类型,常用函数

python str list set dic lambda | filter map reduce | pass,del,exec,eval

from functools import reduce 
foo = [2, 18]
print (list(filter(lambda x: x % 3 == 0, foo))) #[18]
print (list(map(lambda x: x * 2 + 10, foo))) #[14, 46]
print (reduce(lambda x, y: x + y, foo)) #20
print ([x * 2 + 10 for x in foo])
print ([x for x in foo if x % 3 == 0])


二,常用str和list的方法和内置函数

function: cmp(obj1, obj2) len(obj1) max(obj1) min(obj1) sum() reduce() list<==>tuple

# str() 'abc' "abc" '''abc'''
.find(substring, [start [,end]]).rfind(substring,[start [,end]])
.index(substring,[start [,end]])rindex(substring,[start [,end]])
.replace(old, new)..count(substring,[start [,end]])
.lowercase().capitalize().lower().upper().swapcase()
.split(str, ' ')S.join(list, ' ')
.encode([encoding,[errors]]).decode([encoding,[errors]]) 
.startwith(prefix[,start[,end]]) .endwith(suffix[,start[,end]]) 
.isalnum().isalpha().isdigit().isspace().islower().isupper().istitle()

# list() [1, 3, 5]
.append(obj).count(obj).extend(seq).index(obj).insert(index, obj).
pop(obj=list[-1]).remove(obj).reverse().sort([func])

# dict() and collections.OrderedDict()
.get(key, 0).has_key(key).keys().values().items()
.update(dict2).popitem().clear().copy()

# type()
type([]) # <type 'list'>
type([]).__name__ # 'list'
type(type([])) # <type 'type'>
isinstance(varName,varType) # True False

# set() {1, 3, 5}
.add().pop().remove() 
比较元素-->difference()
删除两集合中相同的元素-->difference_update()
移除元素-->discard(values)
取交集值-->intersection()
取交集并更新-->intersection_update()
对称交集-->symmetric_difference()
对称交集并更新-->symmetric_difference_update()
并集-->union()


三,正则表达式re库

1)正则表达式基础

# re库的主要功能函数
# re库是Python的标准库,主要用于字符串匹配
# re库采用raw string类型表示正则表达式,表示为:r'text',raw string不包含转义字符串。
# Re库默认采用贪婪匹配,即输出匹配最长的子串

re.search()     #在一个字符串中搜索匹配正则表达式的第一个位置,返回match对象
re.match()      #从一个字符串的开始位置起匹配正则表达式,返回match对象
re.findall()    #搜索字符串,以列表类型返回全部能匹配的子串
re.split()      #将一个字符串按照正则表达式匹配结果进行分割,返回列表类型
re.finditer()   #搜索字符串,返回一个匹配结果的迭代类型,每个迭代元素是match对象
re.sub()        #在一个字符串中替换所有匹配正则表达式的子串,返回替换后的字符串

#   .	    表示任何单个字符	
#   [ ]	    字符集,对单个字符给出取值范围	[abc]表示a、b、c,[a‐z]表示a到z单个字符
#   [^ ]	非字符集,对单个字符给出排除范围	[^abc]表示非a或b或c的单个字符
#   *	    前一个字符0次或无限次扩展	abc* 表示ab、abc、abcc、abccc等
#   +	    前一个字符1次或无限次扩展	abc+ 表示abc、abcc、abccc等
#   ?	    前一个字符0次或1次扩展	abc? 表示ab、abc左右表达式任意一个
#   {m}	    扩展前一个字符m次	ab{2}c表示abbc
#   {m,n}	扩展前一个字符m至n次(含n)	ab{1,2}c表示abc、abbc
#   ^	    匹配字符串开头	^abc表示abc且在一个字符串的开头
#   $	    匹配字符串结尾	abc$表示abc且在一个字符串的结尾
#   ( )	    分组标记,内部只能使用	操作符
#   \d	    数字,等价于[0‐9]	
#   \w	    单词字符,等价于[A‐Za‐z0‐9_]	
#   \b	    匹配单词的开始或结束
#   \W	    非单词字符,等价于[^\w]	

#贪婪匹配与最小匹配
#  *?      前一个字符0次或无限次扩展,最小匹配
#  +?      前一个字符1次或无限次扩展,最小匹配
#  ??      前一个字符0次或1次扩展,最小匹配
#  {m,n}?  扩展前一个字符m至n次(含n),最小匹配

# reGroups = re.match(r'^(\d+?)(0*)$', '102300')
# reGroups = re.search(r'[1-9]\d{5}', 'BIT 100081')
# reGroups = re.finditer(r'[1-9]\d{5}', 'BIT100081 TSU100084')

htmlList = re.findall(r'(20(?:\d){6})', fileName.upper())
findList = re.findall(r'[1-9]\d{1}', 'BIT100081 TSU100084') # ['10', '81', '10', '84'] 
spltList = re.split(r'[1-9]\d{5}', 'BIT100081 TSU100084') # ['BIT', ' TSU', '']
subinStr = re.sub(r'[1-9]\d{5}', ':zipcode', 'BIT100081 TSU100084') # 'BIT:zipcode TSU:zipcode'


2)正则表达式 高阶

1,懒惰匹配和贪婪匹配,python中的正则表达式默认为惰性匹配。
贪婪匹配,尽量匹配最长串;懒惰匹配,尽量匹配最短串,
>>> s = '<xxxx><xxxx><xxxx><xxxx>'
>>> re.findall('<.*>', s)  # ['<xxxx><xxxx><xxxx><xxxx>']
>>> re.findall('<.*?>', s) # ['<xxxx>', '<xxxx>', '<xxxx>', '<xxxx>']

# *?,+?,??,{m,n}?    前面的*,+,?等都是贪婪匹配,也就是尽可能匹配,后面加?号使其变成惰性匹配
a = re.findall(r"a(\d+?)",'a23b') # ['2']
b = re.findall(r"a(\d+)",'a23b') # ['23']
a = re.match('<(.*)>','<H1>title<H1>').group() # <H1>title<H1>
b = re.match('<(.*?)>','<H1>title<H1>').group() # <H1>
a = re.findall(r"a(\d+)b",'a3333b')  # ['3333']
b = re.findall(r"a(\d+?)b",'a3333b') # ['3333']
# 注意如果前后均有限定条件的时候,就不存在贪婪模式了,非匹配模式失效。

注意体会如下差异:
b = re.findall(r"a\d+?b",'a3333b3333b') # ['a3333b']
b = re.findall(r"a(\d+?)b",'a3333b3333b') # ['3333']
b = re.findall(r"a(?:\d+?)b",'a3333b3333b') # ['a3333b']

b = re.findall(r"a(?:\d+?)b(?:\d+?)b",'a3333b3333b') # ['a3333b3333b']
b = re.findall(r"a(\d+?)b(\d+?)b",'a3333b3333b') # [('3333', '3333')]
b = re.findall(r"a(\d+?)b(?:\d+?)",'a3333b3333b') # ['3333']


2,匹配模式中的分组内容
(.*) 匹配括号内的表达式,也表示一个组, 组里面的内容,可以使用 \1...\9 进行分组提取
>>> s = "i=and love u=you"
>>> re.sub(r'(\w+)=(\w+)', r"[\1]:[\2]", s) # '[i]:[and] love [u]:[you]'

3,前向界定符,包括前向肯定界定符和前项否定界定符
(?=...)前向肯定界定符。如果所含正则表达式,以 ... 表示,在当前位置成功匹配时成功,否则失败。
(?!...)前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功

.*[.].*$ 匹配一个文件名,基本名和扩展名两部分
.*[.](?!bat$).*$ 匹配的扩展名不是 "bat" 的文件名,前向的意思:如果表达式 bat 在这里没有匹配,尝试模式的其余部分;
.*[.](?!bat$|exe$).*$ 匹配不是以 "bat" 或 "exe" 结尾的文件名,如果 bat$ 或者 exe$ 匹配,整个模式将匹配失败。
.*[.](?=bat|exe).*$ 前向肯定界定符,当前位置肯定是这几个字符,匹配成功继续,失败整个表达式失败,

>>> re.findall("[.]((?!bat|exe)\w)", q)  # ['f']
>>> re.findall("[.]((?=bat|exe)\w)", q)  # ['b', 'e']

注意:qinaixnag前向界定符,并不占位,只用来做限定用,限定后具体提取多少位,由后面匹配原则定。
前向界定的字符串长度必须是常数,所以数量词 *  +  {} 胡扯,我试了27版本 * + [] 可以正常使用。


四,python2和3常见编码问题

1,文件编码,比如文件包含中文常量解码格式,2,字符串变量编码存储格式,3.控制台打印输出字符串编码的格式
2,文件的coding编码声明只代表了文件中包含字符串常量中字符以何种解码去读入,根据指定的coding编码格式解码。
coding只是告诉python使用哪种编码来读取python脚本文件,但是文件实际存储编码还是要使用跟coding一致才正确。
字符串常量u"你好"代表对去这个常量,使用以 Unicode 格式 进行编码
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# -*- coding: GB2312-*-
#coding: UTF-8 
#-*- for beauty ctring
with open(‘file.txt’, 'r' , encoding =‘utf-8’) as f: pass

2,字符串变量内存存储编码Unicode格式,内存永远存储二进制byte字节。也不限制编码格式。
内存也可存储utf-8,gbk,gb2312编码的二进制字节,只要存储成Unicode控制台打印就不会乱码。
win下office的excel读取的字符大多需要gbk解码,
调用encode方法的是unicode对象,生成的是字节流;调用decode方法的是str对象(字节流)
sys.setdefaultencoding() 是python2设置默认的string的编码格式,python3默认utf-8编码
sys.getdefaultencoding()是python2(ascii)和3(utf-8)通用的获取python字符串编码格式

python2 sys.getdefaultencoding() #'ascii' 
python3 sys.getdefaultencoding() #'utf-8' 

#为了防止重新设置默认编码影响原本依赖ASCII编码的程序,
#Python编译器在启动时特意清除了sys模块的setdefaultencoding方法。
#如果需要调用,也可以reload(sys)再重载sys模块,它就是变成了第三方模块,可以随便更改,不会影响编译

#输入 (文件/表格 保存文件编码格式 指定读取解码格式,以及控制台输入字符串 终端输入编码:sys.stdin.encoding)
#存储 (来自于文件及变量的字符串,不管什么编码格式,统一按照字节读取存储byte二进制。不改变原有编码)
#输出 (从内存中按照字节取出,对于win控制台只支持gbk,如果原有字符串是bgk编码直接输出显示正常,
#原有编码utf-8,需要先解码unicode再编码gbk合适)

#(如果存储的是unicode则需要进行编码,在win下面控制台unicode字符串打印正产输出。print函数,
# 会对输出的内容编码,终端输出编码:sys.stdout.encoding)
#(对于linux和苹果机器,控制台支持utf-8,如果原有字符串是utf-8编码直接输出显示正常,
# 原有编码gbk,需要先解码unicode再编码gb)
#(如果什么都不指定,那应该就是使用ascii编码了,包含双字节在进行输出
# 编码都会报错提示ascii相关的问题。指定默认内存编码)
# 例如:文件coding指定utf-8,字符串定义带u"你好",在win下控制台输出,即:文件要用utf-8保存,
# 读取使用utf-8解码,将你好使用unicode保存,输出在进行gbk编码
# 如果字符串定义不带u,意味着读取解码utf-8使用存储也会使用使用utf-8,

#你可以通过以下命令查看当前环境的编码来源:
import locale
locale.getpreferredencoding()
locale.getdefaultlocale()


备注:
读写文件的时候,为了防止默认编解码抛异常,建议通过rb或者wb读写二进制文件,py2和py3都支持byte类型字符串。


五,Python里的OS模块常用函数说明

os.sep可以取代操作系统特定的路径分隔符。windows下为"\\"
os.name字符串指示你正在使用的平台。Windows它是'nt',Linux/Unix用户,它是'posix'
os.getcwd()函数得到当前工作目录,即当前Python脚本工作的目录路径。
os.getenv()获取一个环境变量,如果没有返回none
os.putenv(key, value)设置一个环境变量值
os.listdir(path)返回指定目录下的所有文件和目录名。
os.remove(path)函数用来删除一个文件。
os.system(command)函数用来运行shell命令。
os.linesep字符串给出当前平台使用的行终止符。Windows使用'\r\n',Linux使用'\n'而Mac使用'\r'
os.curdir:返回当前目录('.')
os.chdir(dirname):改变工作目录到dirname
os.path.split(p)函数返回一个路径的目录名和文件名
os.path.isfile()和os.path.isdir()函数分别检验给出的路径是一个文件还是目录
os.path.exists()函数用来检验给出的路径是否真地存在
os.path.getsize(name):获得文件大小,如果name是目录返回0L
os.path.abspath(name):获得绝对路径
os.path.normpath(path):规范path字符串形式
os.path.splitext():分离文件名与扩展名
os.path.join(path,name):连接目录与文件名或目录
os.path.basename(path):返回文件名
os.path.dirname(path):返回文件路径


六,Python里的logging模块使用方法

def log:()
    import logging
    logging.basicConfig(level=logging.INFO,
        format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
      datefmt='%a, %d %b %Y %H:%M:%S',
      filename='parser_result.log',
      filemode='w')
    console = logging.StreamHandler()
    console.setLevel(logging.INFO)
    formatter = logging.Formatter('LINE %(lineno)-4d : %(levelname)-8s %(message)s')
    console.setFormatter(formatter)
    logging.getLogger('').addHandler(console)
    logging.info('helloworld')


七,python中import寻找module模块的顺序

首选这个module是不是built-in即内建模块,如果是则引入内建模块,如果不是则在sys.path的list中寻找
sys.path在python执行时动态生成,A脚本执行的当前路径,B环境变量中的PYTHONPATH, C安装python时的依赖位置


八,变量作用域

1,块级作用域:python没有,比如if for里面定义的变量外层可用
2,局部作用域:python有,函数里面定义的变量外部不可用
3,作用域链:Python中有,变量会由函数内到外找,作用域执行前已定
4,函数在没有执行前,内部代码不执行,这点Python和javascript有共性
li = [lambda :x for x in range(10)] 
print(type(li[0]))
print(li[0]()) # 9
5,函数内部的变量,无global声明直接使用,会去查找外层当做全局变量使用,不可赋值
6,函数内部的变量,如果不加global声明直接赋值定义,会被当做局部变量,跟全局无关

函数定义了本地作用域,而模块定义的是全局作用域。
如果想要在函数内定义全局作用域,需要加上global修饰符。



---------------------------------------------------------------------



正则表达式补充:

re.search()      #在一个字符串中搜索匹配正则表达式的第一个位置,返回match对象
re.match()      #从一个字符串的开始位置起匹配正则表达式,返回match对象
re.finditer()      #搜索字符串,返回一个匹配结果的迭代类型,每个迭代元素是match对象

re.findall()      #搜索字符串,以列表类型返回全部能匹配的子串,返回列表类型
re.split()      #将一个字符串按照正则表达式匹配结果进行分割,返回列表类型
re.sub()       #在一个字符串中替换所有匹配正则表达式的子串,返回替换后的字符串


1、普通字符和11个元字符:

普通字符
匹配自身
abc
abc
.
匹配任意除换行符"\n"外的字符(在DOTALL模式中也能匹配换行符
a.c
abc
\
转义字符,使后一个字符改变原来的意思
a\.c;a\\c
a.c;a\c
*
匹配前一个字符0或多次
abc*
ab;abccc
+
匹配前一个字符1次或无限次
abc+
abc;abccc
?
匹配一个字符0次或1次
abc?
ab;abc
^
匹配字符串开头。在多行模式中匹配每一行的开头^abc
abc
$
匹配字符串末尾,在多行模式中匹配每一行的末尾abc$
abc
|或。匹配|左右表达式任意一个,从左到右匹配,如果|没有包括在()中,则它的范围是整个正则表达式
abc|def
abc
def
{}{m}匹配前一个字符m次,{m,n}匹配前一个字符m至n次,若省略n,则匹配m至无限次
ab{1,2}c
abc
abbc
[]
字符集。对应的位置可以是字符集中任意字符。字符集中的字符可以逐个列出,也可以给出范围,如[abc]或[a-c]。[^abc]表示取反,即非abc。
所有特殊字符在字符集中都失去其原有的特殊含义。用\反斜杠转义恢复特殊字符的特殊含义。
a[bcd]e
abe
ace
ade
 
()
被括起来的表达式将作为分组,从表达式左边开始没遇到一个分组的左括号“(”,编号+1.
分组表达式作为一个整体,可以后接数量词。表达式中的|仅在该组中有效。
(abc){2}
a(123|456)c
abcabc
a456c


2、预定义字符集(可以写在字符集[...]中) 

\d
数字:[0-9]
a\bc
a1c
\D
非数字:[^\d]
a\Dc
abc
\s
匹配任何空白字符:[<空格>\t\r\n\f\v]
a\sc
a c
\S非空白字符:[^\s]
a\Sc
abc
\w
匹配包括下划线在内的任何字字符:[A-Za-z0-9_]
a\wc
abc
\W
匹配非字母字符,即匹配特殊字符
a\Wc
a c
\A
仅匹配字符串开头,同^\Aabc
abc
\Z
仅匹配字符串结尾,同$
abc\Z
abc
\b

匹配\w和\W之间,即匹配单词边界,也就是指单词和空格间的位置。

例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。

\babc\b
a\b!bc
 abc 
a!bc
\B
[^\b]
a\Bbc
abc


3,正则表达式模式汇总:

模式描述
^匹配字符串的开头
$匹配字符串的末尾。
.匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。
[...]用来表示一组字符,单独列出:[amk] 匹配 'a','m'或'k'
[^...]不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。
re*匹配0个或多个的表达式。
re+匹配1个或多个的表达式。
re?匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式
re{ n}精确匹配 n 个前面表达式。例如, o{2} 不能匹配 "Bob" 中的 "o",但是能匹配 "food" 中的两个 o。
re{ n,}匹配 n 个前面表达式。例如, o{2,} 不能匹配"Bob"中的"o",但能匹配 "foooood"中的所有 o。"o{1,}" 等价于 "o+"。"o{0,}" 则等价于 "o*"。
re{ n, m}匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式
a| b匹配a或b
(re)匹配括号内的表达式,也表示一个组
(?imx)正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。
(?-imx)正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。
(?: re)类似 (...), 但是不表示一个组
(?imx: re)在括号中使用i, m, 或 x 可选标志
(?-imx: re)在括号中不使用i, m, 或 x 可选标志
(?#...)注释.
(?= re)前向肯定界定符。如果所含正则表达式,以 ... 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎根本没有提高;模式的剩余部分还要尝试界定符的右边。
(?! re)前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功
(?> re)匹配的独立模式,省去回溯。
\w匹配字母数字及下划线
\W匹配非字母数字及下划线
\s匹配任意空白字符,等价于 [\t\n\r\f].
\S匹配任意非空字符
\d匹配任意数字,等价于 [0-9].
\D匹配任意非数字
\A匹配字符串开始
\Z匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。
\z匹配字符串结束
\G匹配最后匹配完成的位置。
\b匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。
\B匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。
\n, \t, 等.匹配一个换行符。匹配一个制表符。等
\1...\9匹配第n个分组的内容。
\10匹配第n个分组的内容,如果它经匹配。否则指的是八进制字符码的表达式。



遗失的美好:
1,为什么在python交互解释器和直接执行脚本中打印出来的sys.path不一样,交互解释器没有当前路径
2,为什么我从当前路径导入模块,语句报错,包的init文件也有,不明觉厉:form . import moduleX
"import package_name"导入包的本质就是执行该包下的__init__.py文件,并且可以调用其定义的函数




发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
搜索
«   2024年9月   »
1
2345678
9101112131415
16171819202122
23242526272829
30
网站分类
最新留言
文章归档
网站收藏
友情链接
图标汇集
Powered by Z-BlogPHP

  • Copyright ©2021 @liuzong All rights reserved.
  • 陕ICP备17016542号