正则表达式与文件操作
正则表达式
正则表达式是一种被用于从文本中检索符合某些特定模式的文本。
基本匹配
"foo" 匹配所有包含foo的文本
元字符
.fu # 代表任意字符后面跟着fu,这里的字符必须有一个。 所以匹配fu会出错
# 字符集
[Tt]fu # 字符集 大写或者小写t,后面跟着fu
ar[.] # 特殊的表示小写字母 a,后面跟着一个字母 r,再后面跟着一个英文句号 . 字符。
[a-z] # a-z的小写字母
[a-z0-9_-] # a-z的小写字母或者0-9的数字或者_或者-
[^c]ar # 除了字母 c 以外的任意字符,后面跟着字符 a, 再后面跟着一个字母 r
# 重复
# * 零次或者多次
# + 一次或者多次
# ? 零次或一次
[a-z]* # 一行中可以包含任意数量的小写字母。
.* # 任意字符串
\s* # 匹配空字符
c.+t # 一个小写字母 c,后跟任意数量的字符,后跟小写字母 t。
[T]?he # 可选的大写字母 T,后面跟小写字母 h,后跟小写字母 e
[0-9]{2,3} # 匹配至少2位数字但不超过3位(0到9范围内的字符)。其实就是长度
[0-9]{2} # 匹配正好为2位数的数字。
[0-9]{2,} # 匹配2个或更多个数字
[a-f]{4} # 匹配一个字符,这个字符需要有连续4个字符,字符内容是a-f中的字母
(c|g|p)ar # 小写字母 c、g 或 p 后面跟字母 a,后跟字母 r。
(f|c|m)at\.? # 小写字母 f、c 或者 m 后跟小写字母 a,后跟小写字母 t,后跟可选的 . 字符。
^(T|t)he # 大写字母 T 或小写字母 t 是输入字符串的起始符号,后面跟着小写字母 h,后跟小写字母 e。
ick$ 匹配以ick结尾的字符
fu\b 匹配以fu结尾的字符
(at\.)$ # 小写字母 a,后跟小写字母 t,后跟一个 . 字符,且这个匹配器必须是字符串的结尾。
(.*?)匹配任意字符0次或多次,模式为非贪婪模式
:(.*?)你 #小括号提取内容,直接将会出来`:我的你`,如果只要匹配`我的`,那么需要加上括号
解释.*
与.*?
的区别
.
代表除换行符外的字符
*
代表匹配它前面的字符0次或者任意多次
.*
代码匹配一串任意长度的字符任意次,贪婪模式,获取最长能满足条件的字符串
?
限制返回,返回最短字符串,而不是整个字符
.*?
匹配能满足要求的最短字符,非贪婪模式,获取最短能满足条件的字符串
{} () []
- {2,3} 花括号 频次
- (.*?) 选中 匹配 括号不包括控制两端
- [] 范围,匹配到的东西必须出现在这个中括号里面
简写字符集
简写 | 描述 |
---|---|
. | 匹配除换行符以外的任意字符 |
\w | 匹配所有字母和数字的字符,不包括空格和双引号: [a-zA-Z0-9_] |
\W | 匹配非字母和数字的字符: [^\w] |
\d(digital) | 匹配数字: [0-9] |
\D | 匹配非数字: [^\d] |
\s | 匹配空格符: [\t\n\f\r\p{Z}] |
\S | 匹配非空格符: [^\s] |
引用
这个\1 \2...... 都要和正则表达式集合()一起使用简单的说就是\1表示重复正则第一个圆括号内匹配到的内容\2表示重复正则第二个圆括号内匹配到的内容
(...).*\1 # 三个字的任意字符,后面再加上某个字符(或者没有),再将这三个字符重复一遍
正则模块
re
findall
以列表的形式返回所有满足要求的字符串,所以要再读取,要加上引号search
返回第一个满足要求的字符串
findall
findall(pattern, str, flags)
# pattern 正则
# str 原来的字符串
# flags 特殊功能的标识符:忽略大小写、忽略换行符等
# re.S 忽略换行符
# return 返回一个匹配的列表,如果没有匹配到,就返回空列表
import re
content_text = '我的微博密码是:12345678,银行卡密码是:98888,github密码是:aasdad123,'
password_list = re.findall(':(.*?),', content_text)
print("找到内容,返回{}".format(password_list))
content_text2 = '我的微博账户是:1232,密码是:12345678,银行卡账户是:123213,密码是:98888,github账户是:git,密码是:aasdad123,记住他们'
password_list2 = re.findall('账户是:(.*?),密码是:(.*?),', content_text2)
print("找到内容,返回{}".format(password_list2))
content_text3 = '''
我是kingname,我的微博密码是:123
456,
'''
password_list3 = re.findall('密码是:(.*?),',content_text3, re.S)
print('密码是{}'.format(password_list3))
search
search只会返回第一个满足要求的字符串,一旦找到符合要求的内容,它会自动停止查找。
返回结果:如果匹配成功,返回正则表达式对象,否则的话,返回None,获取匹配结果,需要使用group, group的参数最大不超过正则表达式里面括号的个数,参数为1表示读取第一个括号的你日工,参数为2表示读取第二个括号的内容
re.search(pattern, string, flags=0)
import re
# search的使用
account_content = '微博账户是: vine, 密码是: 123456, 微信密码是: abs123, qq密码是: 485uiu,'
account_password = re.search('账户是: (.*?), 密码是: (.*?),', account_content)
print("账户:{}".format(account_password.group(1)))
print("密码:{}".format(account_password.group(2)))
技巧
- 使用
findall
,不使用compile - 先抓大再抓小
- 括号内和括号外
搜索密码
# 今天是一个好天气 password:123456:password.我在读书,书的第二页写着password:qwer1234:password啊.
import re
with open('password.txt', encoding='utf-8') as f:
text_content = f.read()
password = re.findall('password:(.*?):password', text_content)
print(password)
抓大放小
import re
big_small_text = '''
有效的用户:
姓名:张三
姓名:李四
姓名:王五
无效的用户:
姓名:不知名的小虾米
姓名:隐身的源大侠
'''
user_list = re.findall('有效的用户:(.*?)无效的用户', big_small_text, re.S)
useful_user_list = re.findall('姓名:(.*?)\n', user_list[0])
print(useful_user_list)
文件操作
创建文件夹
- 参数1:创建文件夹的名称
- 参数2 :如果已存在文件夹,是否保留原来文件夹并不再重新创建
os.makedirs('动物农场', exist_ok=True)
创建文件
- 参数1:要创建文件的文件夹
- 参数2:文件名称
file_path = os.path.join('动物农场', chapter + '.txt')
with open(file_path, 'w', encoding='utf-8') as f:
f.write(article)
打开文件
# 方法一:需要手动关闭文件
f = open('文件路径','文件操作方式',encoding='utf-8');
# 对文件进行操作
f.close()
# 方法二:代码缩进自动关闭文件
with open('文件路径', '文件操作方式', encoding='utf-8') as f:
#对文件进行操作
读取文件
- r ==> read
- 绝对路径/相对路径:linux和Mac OS不能直接使用
~
表示home
目录 - encoding:utf-8 打开文件时将文件转换为utf-8的编码格式
- f.readlines:读取所有行,并以列表的形式返回结果
- f.read() 直接将文件中的所有内容用一个字符串返回
# 读取文本文件
# 按行读取
# 结果 ['1111111111111111111111\n', '2222222222222222222222\n', '333333333333333333333']
with open('text.txt', encoding='utf-8') as f:
content_list1 = f.readlines()
print(content_list1)
# 全部文件读取
# 结果
# 1111111111111111111111
# 2222222222222222222222
# 333333333333333333333
with open('text.txt', encoding='utf-8') as f:
content_list2 = f.read()
print(content_list2)
写入文件
- w ==> write 会覆盖原来的文件
- a ==> append 会将内容加到原来文件的结尾
with open('text.txt', 'w', encoding='utf-8') as f:
通过f来写文件
# 写入文本
with open('text.txt', 'w', encoding='utf-8') as f:
f.write("======写入文本=======\n")
f.write("一大段文字")
f.write("\n===========将列表中的所有字符串写入文本========\n")
f.writelines(["列表元素1", "列表元素2"])
======写入文本=======
一大段文字
===========将列表中的所有字符串写入文本========
列表元素1列表元素2
读写csv文件
读入
import csv
# 返回的是row或者orderedDict(有序字典)
with open('test.csv', encoding='gbk') as f:
reader = csv.DictReader(f)
for row in reader:
print(row)
写入
writer = csv.DictWriter(文件, fieldnames);
# fieldnames的值为字典的key列表
writer.writeheader() #写入csv文件的列名
writer.writerow(单个字典)
writer.writerows(包含字典的列表)
import csv
data = {'访问': '未知', '名称': '某种电脑'}
with open('test.csv', 'a', encoding='gbk') as f:
writer = csv.DictWriter(f, fieldnames=['序号', '访问', '名称'])
writer.writerow(data)