Python编程快速上手 —让繁琐工作自动化(学习记录的笔记随时更新)

"""
Python编程快速上手
—让繁琐工作自动化

网页显示不全,略显麻烦可以复制代码到自己的编辑器查看

笔记
"""
#	**:指数  %:取余数  \\:整除
# 	*号还可以作为字符串复制的操作符:'abc'*2 = 'abcabc'(*号只能用于两个数字 或一个字符串与一个整型数字)
#	一个表达式中使用多个布尔操作符,Python 先求值not 操作符,然后是and 操作符,然后是or 操作符。2 + 2 == 4 and not 2 + 2 == 5 and 2 * 2 == 2 + 2    结果:Ture  and  Ture  and  Ture  =  Ture
#	其他数据类型中的某些值,条件认为它们等价于True 和False。在用于条件时,0、0.0 和' '(空字符串)被认为是False,其他值被认为是True (应用与for  while语句)
#	range()函数也可以有第三个参数。前两个参数分别是起始值和终止值,第三个参数是“步长”(列表切片时一样)
#   import aa, bb, cc
#	调用sys.exit()函数,可以让程序终止或退出。(先导入sys模块)
#	每个函数调用都会返回一个值, print()也是一个函数,其返回一个None;在幕后,对于所有没有return 语句的函数定义,Python 都会在末尾加上return None。这类似于while 或for 循环隐式地以continue 语句结尾
#	print()函数内有可选参数end 和 sep ; end指末尾打印什么,默认值为末尾添加换行符。  sep指在打印参数之间用什么来分隔开他们,默认为空格; 两个可选的默认实参可以自行替换。
print('cats', 'dogs', 'mice', sep='-')	#cats-dogs-mice

#	1.全局作用域中的代码不能使用任何局部变量;
#	2.但是,局部作用域可以访问全局变量;(只有全局变量能用于全局作用域)
#	3.一个函数的局部作用域中的代码,不能使用其他局部作用域中的变量。(一个函数中的局部变量完全与其他函数中的局部变量分隔开来。)
#	4.如果在不同的作用域中,你可以用相同的名字命名不同的变量。也就是说,可以有一个名为spam 的局部变量,和一个名为spam 的全局变量。
#	需要在一个函数内修改全局变量,就使用global 语句  global name 将函数内的变量name  变成全局变量

#	+操作符可以连接合并两个列表;*操作符可以用于复制列表 
#	range(len(列表))可以用来迭代 列表 的所有下标

#	多重赋值技巧:	(变量的数目和列表的长度必须严格相等,否则Python 将给出ValueError:)
cat = ['fat', 'black', 'loud']
size, color, disposition = cat
print(size)
print(color)
print(disposition)

#	用index()方法在列表中查找值的位置:index()方法,可以传入一个值,如果该值存在于列表中,就返回它的下标
spam = ['hello', 'hi', 'howdy', 'heyas']
print(spam.index('howdy'))

#	用sort()对字符串进行排序是大写字母开头永远在小写字母前面['A', 'B', 'a', 'b']

#	字符串和列表实际上很相似,可以认为字符串是单个文本字符的列表。对列表的许多操作,也可以作用于字符串:按下标取值、切片、用于for 循环、用于len(),以及用于in 和not in 操作符。
#	列表和字符串在一个重要的方面是不同的。列表是“可变的”数据类型,它的值可以添加、删除或改变。但是,字符串是“不可变的”,它不能被更改(只能改变指向他的变量,让变量指向另一个字符串)

#	如果元组中只有一个值,你可以在括号内该值的后面跟上一个逗号告诉Python,这是一个元组 ('hello',) 是一个元组。(元组也是不可变的,但元组内的列表可变)
#	>>> tuple(['cat', 'dog', 5])结果:('cat', 'dog', 5)转换成元组,转换列表用list;

#	引用:
#	变量保存字符串和整数值时的情况:	
"""
>>> spam = 42
>>> cheese = spam					#	cheese = spam 等于是把spam的值拷贝给了cheese,即使后面spm值修改了,并不影响cheese。
>>> spam = 100
>>> spam
100
>>> cheese
42	
"""
#	而变量被赋予列表不是这样的。当你将列表赋给一个变量时,实际上是将列表的“引用”赋给了该变量。引用是一个值,指向某些数据。列表引用是指向一个列表的值:
"""
>>> spam = [0, 1, 2, 3, 4, 5]
>>> cheese = spam					#这里的cheese = spam等于是把spam引用列表的值的ID(可以理解为列表的地址)拷贝给了cheese,实际上列表并没有拷贝,所以只要有一方修改了列表,两边变量储存的列表都会变,因为是同一个。
>>> cheese[1] = 'Hello!'
>>> spam
[0, 'Hello!', 2, 3, 4, 5]
>>> cheese
[0, 'Hello!', 2, 3, 4, 5]
"""

"""
		变量包含对列表值的引用,而不是列表值本身。但对于字符串和整数值,变量
	就包含了字符串或整数值。在变量必须保存可变数据类型的值时,例如列表或字典,
	Python 就使用引用。对于不可变的数据类型的值,例如字符串、整型或元组,Python
	变量就保存值本身。
"""

#	当函数被调用时,参数的值被复制给变元。对于列表以及字典,这意味着变元得到的是“引用”的拷贝:
def eggs(someParameter):
	someParameter.append('Hello')
spam = [1, 2, 3]
eggs(spam)
print(spam)		#原列表的最终值会被函数改变,因为函数并未拷贝列表,只是复制了列表的“引用”,若不想列表值被修改可以用元组。

#	copy 模块的copy()和deepcopy()函数:	Python 提供了名为copy 的模块,其中包含copy()和deepcopy()函数。第一个函数copy.copy(),可以用来复制列表或字典这样的可变值,而不只是复制引。
#	也可以用copy()函数直接复制列表而不是复制列表的引用:
"""
>>> import copy
>>> spam = ['A', 'B', 'C', 'D']
>>> cheese = copy.copy(spam)
>>> cheese[1] = 42
>>> spam
['A', 'B', 'C', 'D']
>>> cheese
['A', 42, 'C', 'D']
"""
#	如果要复制的列表中包含了列表,那就使用copy.deepcopy()函数来代替。
#	变量不直接保存列表值,它们保存对列表的“引用”。在复制变量或将列表作为函数调用的参数时,这一点很重要。因为被复制的只是列表引用,所以要注意,
#	循环嵌套的列表可以用aaa[][]来访问元素


#字典:不像列表,字典中的表项是不排序的,同时字典中的键必须是不可变值(str、int等)。

#	get()和 setdefailt()的用法:
#	get(key, 备用值)	方法,它有两个参数:要取得其值的键,以及如果该键不存在时,返回的备用值(防止报错)
picnicItems = {'apples': 5, 'cups': 2}
print(picnicItems.get('orange', 'none'))

#	setdefailt(key, 将要设置的值)要取得其值的键,以及如果该键不存在时要设置的值。如果该键确实存在,方法就会返回键的值。
"""
>>> spam = {'name': 'Pooka', 'age': 5}
>>> spam.setdefault('color', 'black')
'black'
>>> spam
{'color': 'black', 'age': 5, 'name': 'Pooka'}
>>> spam.setdefault('color', 'white')
'black'
"""

#	方法get()和setdefault()的区别在于get()不会修原字典值,只是用来防止错误。setdefault()则会修改原字典,为没有找到值的键或者没有找到的键添加默认设置值。
message = 'It was a bright cold day in April, and the clocks were striking thirteen.'

"""计算message中每个字母出现的次数"""
count = {}
for letter in message:
	count.setdefault(letter, 0)
	count[letter] = count[letter] + 1
import pprint				#	导入pprint 模块,就可以使用pprint()和pformat()函数,它们将“漂亮打印”一个字典的字。pformat()和pprint一样 只是单纯获取其格式不打印
pprint.pprint(count)
pfo = pprint.pformat(count)



"""第六章:字符串操作"""
#	print(r'That is Carol\'s cat.') 输出 :That is Carol\'s cat.  在引号前加上r使它成为原始字符串。“原始字符串”完全忽略所有的转义字符
print('' in 'spm') 

#	由于字符串是不可变的所以upper()、lower()等不会修改字符串本身,而是返回一个新的字符串
#	isupper()和islower()方法用于判断字符串似否都是大小写,相应地返回布尔值True或者Flast:   xxx.islower()	

#	isX 字符串方法: 用法aaa.isX()
"""
isalpha()返回True,如果字符串只包含字母,并且非空;
isalnum()返回True,如果字符串只包含字母和数字,并且非空;
isdecimal()返回True,如果字符串只包含数字字符,并且非空;
isspace()返回True,如果字符串只包含空格、制表符和换行,并且非空;
istitle()返回True,如果字符串仅包含以大写字母开头、后面都是小写字母的单词。
"""
#	字符串方法startswith()和endswith()用法和上面一样,括号内传入要检查的内容,用于检查字符串开头或结尾是否与实参一致。

#	join()方法在一个字符串上调用,参数是一个字符串列表,返回一个字符串,返回的字符串由传入的列表中每个字符串连接而成。(作用在字符串上,传入列表,将列表转换成为字符串,连接他们的就是调用join()上的字符串)
#	split()方法做的事情正好相反:它针对一个字符串调用,返回一个字符串列表。(作用在字符串上,传入字符串参数,根据传入字符串作为分隔条件,将字符串转换成为列表)。可以用\n换行符来分割,返回列表中的每个表项,对应于字符串中的一行。
'''
>>> 'ABC'.join(['My', 'name', 'is', 'Simon'])
>>> 'MyABCnameABCisABCSimon'

>>> 'My name is Simon'.split()
['My', 'name', 'is', 'Simon']

MyABCnameABCisABCSimon'.split('ABC')
['My', 'name', 'is', 'Simon']
'''

#用rjust()、ljust()和center()方法对齐文本:
"""
>>> 'Hello'.rjust(20, '*')
'***************Hello'
>>> 'Hello'.ljust(20, '-')				# 第二个参数为可选参数,默认为空格
'Hello---------------'
>>> 'Hello'.center(20, '=')
'=======Hello========'
"""

#	strip()、rstrip()和lstrip() 分别用于删除两边、右边和左边空白字符(也可以向它们传入字符串实参,删除两边对应的字符串)

#	pyperclip 模块拷贝粘贴字符串:pyperclip 模块有copy()和paste()函数,用来复制和粘贴剪切板(需要安装第三方模块)

import pyperclip
pyperclip.copy('Hello world!')
a = pyperclip.paste()
print(a)

#	关于命令行参数sys.argv[1]:表示在运行命令提示符中运行py文件时输出的值就是sys.argv[1],而sys.argv[0]则是这个变量本身(例如在C盘根目录运行cmd命令:C:\abc.pw AAAA  那sys.argv[1]为AAA)




"""--------------------------------------------------------------第二部分---------------------------------------------------------------------"""



#	正则表达式

"""不使用正则表达式查找号码。"""
def isPhoneNumber(text):		#号码格式为XXX-XXX-XXXX
	if len(text) != 12:
		return False
	for i in range(0, 3):
		if not               text[i].isdecimal():
			return False
	if text[3] != '-':
		return False
	for i in range(4, 7):
		if not text[i].isdecimal():	
			return False
	if text[7] != '-':
		return False
	for i in range(8, 12):
		if not text[i].isdecimal():
			return False
	return True
message = 'Call me at 415-555-1011 tomorrow. 415-555-9999 is my office.'
for i in range(len(message)):
	chunk = message[i:i+12]
	if isPhoneNumber(chunk):
		print('Phone number found: ' + chunk)
print('Done')

#	使用正则表达式查找(正则表达式,简称为regex,是文本模式的描述方法)
import re																#	Python 中所有正则表达式的函数都在re 模块中。	\d 表示一个数字字符; \d{3}表示匹这个数字3次(就是3位数);
phoneNumRegex = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d')					#	Regex 对象的search()方法查找传入的字符串
mo = phoneNumRegex.search('My number is 415-555-4242.')					#	如果字符串中没有找到该正则表达式模式,search()方法将返回None。如果找到了该模式,search()方法将返回一个Match 对象(此处是mo为非空的则为Match对象)
print('Phone number found: ' + mo.group())								#	Match 对象有一个group()方法,它返回被查找字符串中实际匹配的文本

"""
在Python 中使用正则表达式有几个步骤,但每一步都相当简单。
1.用import re 导入正则表达式模块。
2.用re.compile()函数创建一个Regex 对象(记得使用原始字符串)。
3.向Regex 对象的search()方法传入想查找的字符串。它返回一个Match 对象。
4.调用Match 对象的group()方法,返回实际匹配文本的字符串。
"""

print('利用括号分组')

#	添加括号将在正则表达式中创建“分组”:(\d\d\d)-(\d\d\d-\d\d\d\d)。然后可以使用group()匹配对象方法,从一个分组中获取匹配的文本。
phoneNumRegex = re.compile(r'(\d\d\d)-(\d\d\d-\d\d\d\d)')
mo = phoneNumRegex.search('My number is 415-555-4242.')	
print(mo.groups())														#	groups返回多个值的元组。
print(mo.group(0))														#	group非复数情况下不传入参数和传入0一样代表返回整个匹配文本。
print(mo.group(1))
print(mo.group(2))
aa, bb = mo.groups()													#	注意此处的groups  为复数后面有s
print(aa)

#	传递给re.compile()的原始字符串中,\(和\)转义字符将匹配实际的括号字符(同理想要正则表达式中匹配\ . ?等特殊符号 可以用转义符进行转义)。

"""	#	正则表达式符号:
	?匹配零次或一次前面的分组。					#此分组并非一定是()分组,可以是单个字符
	*匹配零次或多次前面的分组。
	+匹配一次或多次前面的分组。
	{n}匹配n 次前面的分组。
	{n,}匹配n 次或更多前面的分组。
	{,m}匹配零次到m 次前面的分组。
	{n,m}匹配至少n 次、至多m 次前面的分组。
	{n,m}?或*?或+?对前面的分组进行非贪心匹配。
	^spam 意味着字符串必须以spam 开始。
	spam$意味着字符串必须以spam 结束。
	.表示“通配符”匹配所有字符,换行符除外。 (可以用.*号匹配所有字符,默认使用贪心模式)
	\d、\w 和\s 分别匹配数字、字母、数字或下划线字符(可以认为是匹配“单词”字符)和空格、制表符、换行符。
	\D、\W 和\S 分别匹配数字、字母、数字或下划线字符(可以认为是匹配“单词”字符)和空格、制表符、换行符 外 的所有字符。
	[abc]匹配方括号内的任意字符(诸如a、b 或c)。 注意方括号内所有表达式符号会被解释,不需要写成\?  \) 或者\.
	[^abc]匹配不在方括号内的任意字符。
	|字符称为“管道”,匹配许多表达式中的一个时,,第一次出现的匹配文本,将作为Match 对象返回。
	字符分类[aeiouAEIOU]将匹配所有元音字符,不论大小写  [0-9]匹配所有数字字符
	
"""

batRegex = re.compile(r'Batwo?man')			# 	?匹配零次或一次前面的分组。	
mo1 = batRegex.search('The Adventures of Batwman')
print(mo1.group())

print('findall()方法')
#	除了search 方法外,Regex 对象也有一个findall()方法。search()将返回一个Match对象,包含被查找字符串中的“第一次”匹配的文本,而findall()方法将返回一组字符串,包含被查找字符串中的所有匹配。

phoneNumRegex = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d') # has no groups
print(phoneNumRegex.findall('Cell: 415-555-9999 Work: 212-555-0000'))	#另一方面,findall()不是返回一个Match 对象,而是返回一个字符串列表
#	output:['415-555-9999', '212-555-0000']		(返回一个列表)

#	如果在正则表达式中有分组,那么findall 将返回元组的列表
phoneNumRegex = re.compile(r'(\d\d\d)-\d\d\d-(\d\d\d\d)') # has groups
print(phoneNumRegex.findall('Cell: 415-555-9999 Work: 212-555-0000'))	#	
#	output : [('415', '9999'), ('212', '0000')]							注意 只返回有分组的部分 


#	也可以用句点号.匹配换行符,例如像re.compile()传递第二参数re.DOTALL可以让句点字符匹配所有字符,包括换行字符
newlineRegex = re.compile('.*', re.DOTALL)

#	要让正则表达式不区分大小写,可以向re.compile()传入re.IGNORECASE 或re.I,作为第二个参数
robocop = re.compile(r'robocop', re.I)

#	用sub()方法替换字符串,Regex对象的sub()方法需要传入两个参数。第一个参数是一个字符串,用于取代发现的匹配。第二个参数是一个字符串,即正则表达式
namesRegex = re.compile(r'Agent \w+')									#	sub()方法返回替换完成后的字符串
namesRegex.sub('CENSORED', 'Agent Alice gave the secret documents to Agent Bob.')
#	output:'CENSORED gave the secret documents to CENSORED.'

#	在sub()的第一个参数中,可以输入\1、\2、\3……。表示“在替换中输入分组1、2、3……的文本”。具体用法如下
agentNamesRegex = re.compile(r'Agent (\w)\w*')				
agentNamesRegex.sub(r'\1****', 'Agent Alice told Agent Carol that AgentEve knew Agent Bob was a double agent.')		#	把分组1中的(\w)放在需要替换的字符\1的位置上
#	output: A**** told C**** that E**** knew B**** was a double agent.

#	忽略正则表达式字符串中的空白符和注释,可以向re.compile()传入变量re.VERBOSE,作为第二个参数。(可以将正则表达式放在多行中,并加上注释):
phoneRegex = re.compile(r'((\d{3}|\(\d{3}\))?(\s|-|\.)?\d{3}(\s|-|\.)\d{4}(\s*(ext|x|ext.)\s*\d{2,5})?)')		#这个复杂的正则表达式可以写成下面这样:

phoneRegex = re.compile(r'''(
	(\d{3}|\(\d{3}\))?		 			# area code
	(\s|-|\.)? 							# separator
	\d{3} 								# first 3 digits
	(\s|-|\.) 							# separator
	\d{4} 								# last 4 digits
	(\s*(ext|x|ext.)\s*\d{2,5})? 		# extension
)''', re.VERBOSE)

#	re.compile()函数只接受一个值作为它的第二参数。可以使用管道字符(|)将变量组合起来,从而绕过这个限制。管道字符在这里称为“按位或”操作符
someRegexValue = re.compile('foo', re.IGNORECASE | re.DOTALL | re.VERBOSE)


print("\n项目:电话号码和E-mail 地址提取程序")

"""改程序在此处运行有问题,需要新建一个PY文件单独的把这个程序放进去才能正常获取电话或者邮件"""

import pyperclip, re
phoneRegex = re.compile(r'''(
                        (\d{3}|\(\d{3}\))? # area code
                        (\s|-|\.)?      # separator
                        (\d{3})         # first 3 digits
                        (\s|-|\.)       # separator
                        (\d{4})         # last 4 digits
                        (\s*(ext|x|ext.)\s*(\d{2,5}))? # extension
                        )''', re.VERBOSE)
                        
"""
注意此处正则表达式中的分组0-8,分别对应的位置(号码:800-420-7240 ext 333)对应的分组位置为:
('800-420-7240 ext 333', '800', '-', '420', '-', '7240', ' ext 333', 'ext', '333')
关键的地方为位置为6、7、8的关系。
"""

# 创建一个获取电话号码的正则表达式 

emailRegex = re.compile(r'''(
                        [a-zA-Z0-9._%+-]+ # username
                        @ 		# @ symbol
                        [a-zA-Z0-9.-]+ # domain name
                        (\.[a-zA-Z]{2,4}) # dot-something
                        )''', re.VERBOSE)
# TODO: 创建一个获取邮件地址的正则表达式
# 将剪切板上的字符保存在变量text上.
text = str(pyperclip.paste())
matches = []
for groups in phoneRegex.findall(text):
    phoneNum = '-'.join([groups[1], groups[3], groups[5]])
    if groups[8] != '':
        phoneNum += ' x' + groups[8]									#	groups[8]为座机号
        matches.append(phoneNum)
  
for groups in emailRegex.findall(text):
    matches.append(groups[0])
# TODO: Copy results to the clipboard.
# Copy results to the clipboard.
if len(matches) > 0:
    pyperclip.copy('\n'.join(matches))
    print('Copied to clipboard:')
    print('\n'.join(matches))
else:
    print('No phone numbers or email addresses found.')

#	测试号码正则表达式中分组分别对应的表达式位置
mo =  phoneRegex.search(r'800-420-7240 ext 333').groups()        #	分组位置先数外圈再数内圈,0为整个匹配字符串              
print(mo)       #	output: ('800-420-7240 ext 333', '800', '-', '420', '-', '7240', ' ext 333', 'ext', '333') 分别对应 groups[0]~groups[8]            



 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值