day19正则 进程

一、正则表达式

1.分组匹配

import  re

#() 和  |

#1.
#+:匹配1个或者多个
print(re.search(r"\d+","abc123-d4646gshghg"))
print(re.findall(r"\d+","abc123-d4646gshghg"))
#*:匹配0个或者多个
print(re.search(r"\d*","abc123-d4646gshghg"))
print(re.findall(r"\d*","abc123-d4646gshghg"))

print("=" * 30)

#2.
print(re.search(r"\d+|[a-z]+","abc123-d4646gshghg"))
print(re.findall(r"\d+|[a-z]+","abc123-d4646gshghg"))

print("=" * 30)

#3.
print(re.search(r"(\d+)|[a-z]+","abc123-d4646gshghg"))
"""
注意:使用findall进行搜索,如果正则中没有(),则正常匹配显示
但是,如果正则表达式中出现了(),则findall返回的数据只有()中匹配到的数据
"""
print(re.findall(r"(\d+)|[a-z]+","abc123-d4646gshghg"))
print(re.findall(r"\d+|([a-z]+)","abc123-d4646gshghg"))
"""
<re.Match object; span=(0, 3), match='abc'>
['', '123', '', '4646', '']
['abc', '', 'd', '', 'gshghg']
"""
print(re.findall(r"(\d+)|([a-z]+)","abc123-d4646gshghg"))
#[('', 'abc'), ('123', ''), ('', 'd'), ('4646', ''), ('', 'gshghg')]

print(re.findall(r"(\d+|([a-z]+))","abc123-d4646gshghg"))
#[('abc', 'abc'), ('123', ''), ('d', 'd'), ('4646', ''), ('gshghg', 'gshghg')]

print(re.findall(r"((\d+)|([a-z]+))","abc123-d4646gshghg"))
#(()())
#[('abc', '', 'abc'), ('123', '123', ''), ('d', '', 'd'), ('4646', '4646', ''), ('gshghg', '', 'gshghg')]
#[(外层,左边,右边)],括号的个数决定了返回的列表中元组中元素的个数

print("=" * 30)

#4.
print(re.findall(r"([a-z]\d)+\w+","abc123-d4646gshghg"))
print(re.search(r"([a-z]\d)+\w+","abc123-d4646gshghg"))
"""
['c1','d4']    #c123 d4646gshghg
<re.Match object; span=(2, 6), match='c123'>
"""
print(re.findall(r"(([a-z]\d)+\w+)","abc123-d4646gshghg"))
print(re.search(r"(([a-z]\d)+\w+)","abc123-d4646gshghg"))
"""
[(外层,内层),(),]  [('c123', 'c1'), ('d4646gshghg', 'd4')]
<re.Match object; span=(2, 6), match='c123'>
"""

#5.
#\w可以匹配字母【大写和小写】数字和下划线
print(re.findall(r"([a-z]\d|[A-Z])+\w+","Abc123D-D4646gsHghg"))
print(re.findall(r"(([a-z]\d|[A-Z])+\w+)","Abc123D-D4646gsHghg"))
"""
["A","D"]     Abc123D   D4646gsHghg
[(Abc123D,A),(D4646gsHghg,D)]
"""
#6.
print(re.findall(r"([a-z]\d|[A-Z])+\w","Abc123D-D4646gsHghg"))
print(re.findall(r"(([a-z]\d|[A-Z])+\w)","Abc123D-D4646gsHghg"))
"""
['A', 'c1', 'D', 'H']   #Ab  c12  D4   Hg
[('Ab', 'A'), ('c12', 'c1'), ('D4', 'D'), ('Hg', 'H')]


([a-z]\d|[A-Z])+\w
Ab    c12    D4    Hg 


([a-z]\d|[A-Z])+\w
Abc1c1d5h823D-D4646gsHghg
"""
2.子模式
import  re

"""
正则表达式中的子模式

正则表达式中的()表示一个整体,同时表示子模式
如果在同一个正则表达式中出现了重复的表示规则,则后面出现的可以直接使用前面出现的规则
则从左往右将指定的规则添加(),系统会自动给()进行编号,
从1开始,当后面的规则中需要使用,则只需要使用\1,\2......表示
"""


print(re.search(r"<[a-z]+><\w+>[a-zA-Z0-9]+<\w+><[a-z]+>","<div><span>hello123<span><div>"))

print(re.search(r"<([a-z]+)><(\w+)>[a-zA-Z0-9]+<\2><\1>","<div><span>hello123<span><div>"))

#print(re.findall(r"<([a-z]+)><(\w+)>[a-zA-Z0-9]+<\2><\1>","<div><span>hello123<span><div>"))
3.模式修正
#re.M :多行模式,影响^和$
#re.I :忽略大小写

import  re

#1.
string = """good 123
good  fhajfh
good 2367856"""

print(re.findall(r"^good",string))
print(re.findall(r"^good",string,flags=re.M))
"""
['good']
['good', 'good', 'good']
"""

#2.
print(re.findall(r"a+","12aaaaaaa45656AAAAA"))
print(re.findall(r"a+","12aaaaaaa45656AAAAA",flags=re.I))
"""
['aaaaaaa']
['aaaaaaa', 'AAAAA']
"""

4.常用函数
import  re

#1.compile():将一个正则字符串编译为正则对象
#功能:单独使用没有意义,一般是为了结合其他函数使用
r1 = re.compile(r"\d+")
print(r1,type(r1))

#2.match():使用正则表达式匹配指定的字符串
#功能:根据指定的条件匹配指定的字符串,如果匹配上返回一个对象,如果匹配不上则返回None
r2 = re.match(r"\d+","3465gg")
print(r2)

#3.search():使用正则表达式搜索指定的字符串
#功能:只返回第一次匹配到的结果,如果匹配上,则返回一个对象,如果匹配不上则返回None
r3 = re.search(r"\d+","3465gg")
print(r3)

#4.findall():使用正则表达式搜索指定的字符串
#功能:返回所有匹配到的结果,返回一个列表
r3 = re.findall(r"\d+","3465gg")
print(r3)

print("=" * 30)

#5.finditer():使用正则表达式搜索指定的字符串
#功能:返回所有匹配到的结果,返回一个迭代器,可以遍历获取其中的元素,其中的元素是匹配到的对象
r5 = re.finditer(r"\d+","25535hh-5757hhffj")
print(r5)
#a
# print(next(r5))
# print(next(r5))

#b
# for i in r5:
#     print(i)
#     print(i.group())
#     print(i.span())


#6.split():使用正则表达式分割指定的字符串
#功能:使用指定的规则将指定的字符串进行分割,返回一个列表,
# 如果被分割字符串有规律,则直接使用字符串的split,如果被分割的字符串没有规律,则使用re中的split
str1 = "zhangsan-lisi-jack-tom"
print(str1.split("-"))
print(re.split(r"-",str1))

str1 = "zhangsan-----lisi---jack---------tom"
#print(str1.split("-+"))
print(re.split(r"-+",str1))

str1 = "zhangsan@@@@@@@@Lisi%%%Jack#############Tom&&&&&&&xiaoming"
print(re.split(r"[@%#&]+",str1))
print(re.split(r"[^a-zA-Z]+",str1))

print(re.split(r"[^a-zA-Z]+",str1,2))

#7.sub和subn:使用正则表达式替换指定的字符串,类似字符串中的replace
#功能:sub(old,new,string),返回替换之后的新字符串
str1 = "zhangsan@@@@@@@@Lisi%%%Jack#############Tom&&&&&&&xiaoming"  #zhangsan-lisi-jack-tom"
print(re.sub(r"[@%#&]+","-",str1))
#zhangsan-Lisi-Jack-Tom-xiaoming
print(re.sub(r"[@%#&]+","-",str1,2))

#subn()返回一个元组,(替换之后的新字符串,统计替换的次数)
print(re.subn(r"[@%#&]+","-",str1))
#('zhangsan-Lisi-Jack-Tom-xiaoming', 4)

5.注意的问题
import re

#1.空格的使用
#注意:在正则表达式中注意空格的使用,也是一个字符
print(re.findall(r"\d + \w","35465gfbhjagahj"))   #3 + 5
print(re.findall(r"\d |\w","35465gfbhjagahj"))   #6 | 3

#2.flags的使用
#注意:但凡使用flags,则尽量使用关键字方式传参
print(re.split(r"a","a34y74Afhfha4757A666"))
print(re.split(r"a","a34y74Afhfha4757A666",re.I)) #['', '34y74Afhfh', '4757A666']
print(re.split(r"a","a34y74Afhfha4757A666",flags=re.I)) #['', '34y74', 'fhfh', '4757', '666']
6.练习
import  re
"""
1.用户名匹配 

 要求:	1.用户名只能包含数字 字母 下划线    \w

         2.不能以数字开头 

         3.⻓度在 6 到 16 位范围内
"""
def check_username(name):
 r1 = re.match(r"^[a-zA-Z_]\w{5,15}$",name)
 #r1 = re.match(r"^[a-zA-Z_][a-zA-Z0-9_]{5,15}", name)

 if r1:
     return True
 else:
     return False

"""
2.密码匹配 

     要求:	1.不能包含!@#¥%^&*这些特殊符号

                 2.必须以字母开头 

                 3.⻓度在 6 到 12 位范围内

"""
def check_pwd(pwd):
 r = re.match(r"^[a-zA-Z][^!@#¥%^&*]{5,11}$",pwd)

 # if r:
 #     return True
 # else:
 #     return False

 return True if r else False


"""
4.
ipv4 格式的 ip 地址匹配

提示: IP地址的范围是 0.0.0.0 - 255.255.255.255

192.168.10.45

分析:
 a.组成:1   2    3
 b.1位:[0-9]
 c.2位:[1-9][0-9]   例如:5
 d.3位:
     1xx :[1][0-9][0-9]
     2xx :
         [2][0-4][0-9]
         [2][5][0-5]
"""
def check_ip(ip):
 #一位  \d
 #两位  [1-9]\d
 #三位
 #   [1]\d{2}
 #   [2]([0-4]\d|[5][0-5])

 #(\d|[1-9]\d|[1]\d{2}|[2]([0-4]\d|[5][0-5]))匹配前三段的数字
 #((\d|[1-9]\d|[1]\d{2}|[2]([0-4]\d|[5][0-5]))\.)匹配前三段的数字+ .,但是.本身有特殊含义,需要转义


 regex = r"^((\d|[1-9]\d|[1]\d{2}|[2]([0-4]\d|[5][0-5]))\.){3}" \
         r"(\d|[1-9]\d|[1]\d{2}|[2]([0-4]\d|[5][0-5]))$"
 r  = re.match(regex,ip)
 print(r)

 return  True if r else False

"""
5.提取用户输入数据中的数值 (数值包括正负数 还包括整数和小数在内) 并求和 

负数/正数:  -?   -有0个或者1个
小数:     (\.\d+)?   .有0个或者1个
整数:
 1位 :[0-9]
 多位: [1-9][0-9]*   *可以匹配0个或者多个

[-]?(0|[1-9]\d*)(\.\d+)?
"""
def add(data):
 #如果有()findall返回[(),()],此时finditer可以直接获取到对象
 r = re.finditer(r"[-]?(0|[1-9]\d*)(\.\d+)?",data)
 result = 0
 for num in r:
     print(num.group())
     result += float(num.group())
 return result

if __name__ == "__main__":
 #print(check_ip("10.168.10.30"))
 print(add("fgfg45fhj-7fhjk18.9hfh10"))

二、进程

1.概念
1.1多任务

程序的运行是CPU和内存协同工作的结果

操作系统比如Mac OS X,UNIX,Linux,Windows等,都是支持“多任务”的操作系统

问题1:什么是多任务?

​ 就是操作系统可以同时运行多个任务。打个比方,你一边在用浏览器上网,一边在听MP3,一边在用Word赶作业,这就是多任务,至少同时有3个任务正在运行。还有很多任务悄悄地在后台同时运行着,只是桌面上没有显示而已

问题2:多核CPU已经非常普及了,但是,即使过去的单核CPU,也可以执行多任务。由于CPU执行代码都是顺序执行的,那么,单核CPU是怎么执行多任务的呢?

​ 答案:操作系统轮流让各个任务交替执行,任务1执行0.01秒,切换到任务2,任务2执行0.01秒,再切换到任务3,执行0.01秒……这样反复执行下去。表面上看,每个任务都是交替执行的,但是,由于CPU的执行速度实在是太快了,我们感觉就像所有c任务都在同时执行一样【现在的电脑最起码都4核起】

多核cpu实现多任务的原理:真正的并行执行多任务只能在多核cpu上实现,但是由于任务数量远远远多于cpu的核心数量,所以操作系统也会自动把很多任务轮流调度到每个核心上执行

​ 并行:真正一起执行,任务数量小于等于cpu核心数量【理想型】

​ 并发:看上去一起执行,任务数量多于cpu核心数量【现实型】

对于操作系统来说,一个任务就是一个进程(Process),比如打开一个浏览器就是启动一个浏览器进程,打开一个记事本就启动了一个记事本进程,打开两个记事本就启动了两个记事本进程,打开一个Word就启动了一个Word进程

有些进程还不止同时干一件事,比如Word,它可以同时进行打字、拼写检查、打印等事情。在一个进程内部,要同时干多件事,就需要同时运行多个“子任务”,我们把进程内的这些“子任务”称为线程(Thread)

1.2进程

是一个程序的运行状态和资源占用(内存,CPU)的描述

进程是程序的一个动态过程,它指的是从代码加载到执行完毕的一个完成过程

进程的特点:

​ a.独立性:不同的进程之间是独立的,相互之间资源不共享(举例:两个正在上课的教室有各自的财产,相互之间不共享)

​ b.动态性:进程在系统中不是静止不动的,而是在系统中一直活动的(举例:教室里一直在讲课)

​ c.并发性:多个进程可以在单个处理器上同时进行,且互不影响(举例:天丰利就是个处理器的话,多个教室同时上课就相当于多个进程,c相互之间不影响)

多进程:一个操作系统可以运行多个应用程序

1.3线程

是进程的组成部分,一个进程可以有多个线程,每个线程去处理一个特定的子任务

​ 线程的执行是抢占式的,多个线程在同一个进程中可以并发执行,其实就是CPU快速的在不同的线程之间切换,也就是说,当前运行的线程在任何时候都有可能被挂起,以便另外一个线程可以运行

​ 例如:打开酷狗音乐 ————》这是一个进程

​ 播放歌曲和刷新歌词————》这是两个线程(两个线程在同时执行,所以说是并发的)

​ 一个进程中的不同线程之间是资源共享的

​ 多线程:

​ 在一个进程中,多个线程可以同时进行

​ 多线程是实现了并发机制的一种有效手段,一个进程中可以包含多个线程,不同线程之间是可以资源共享的,同时运行可以提高程序的执行效率,可以同时完成多个工作

​ 应用:一个浏览器可以同时下载多张图片和多个视频

​ 一个服务器可以同时响应多个用户请求

1.3进程和线程之间的关系【面试题】

​ a.一个程序运行后至少有一个进程

​ b.一个进程可以包含多个线程,但是至少需要有一个线程,否则这个进程是没有意义的

​ c.进程间不能共享资源,但线程之间可以

​ d.系统创建进程需要为该进程重新分配系统资源,而创建线程则容易的多,因此使用线程实现多任务并发比多进程的效率高

思考问题:前面编写的所有的Python程序,都是执行单任务的进程,也就是只有一个线程。如果我们要同时执行多个任务怎么办?

多任务的实现有3种方式:

​ a.多进程模式:启动多个进程,每个进程虽然只有一个线程,但多个进程可以一块执行多个任务

​ b.多线程模式:启动一个进程,在一个进程内启动多个线程,这样,多个线程也可以一块执行多个任务

​ c.协程模式

​ d.多进程+多线程模式:启动多个进程,每个进程再启动多个线程,这样同时执行的任务就更多了

Python既支持多进程,又支持多线程,我们会讨论如何编写这两种多任务程序

2.实现

2.1单任务现象
"""
from time import  sleep

def run():
 #任务二
 while True:
     print("today is a nice day")
     sleep((2))


if __name__ == "__main__":
 #任务一
 while True:
     print("hello")
     sleep(1)

 #不会执行到run函数,只有上面的while循环结束才可以执行【按照顺序执行】
 run()
"""

2.2启动进程实现多任务

#Python中提供了一个跨平台的多进程模块,其中的Process类可以用来创建进程对象
from multiprocessing import  Process
from time import  sleep
import  os

#无参
def run():
 #3.os.getpid()获取当前进程的进程号,os.getppid()获取当前进程的父进程的进程号
 print("子进程启动~~~%s,对应的父进程:%s" % (os.getpid(),os.getppid()))
 while True:
     print("today is a nice day")
     sleep(1.2)
#有参
def run1(num):
 #3.os.getpid()获取当前进程的进程号,os.getppid()获取当前进程的父进程的进程号
 print("子进程启动~~~%s,对应的父进程:%s" % (os.getpid(),os.getppid()))
 print(num)
 while True:
     print("today is a nice day")
     sleep(1.2)

if __name__ == "__main__":
 #1.__main__中执行的代码表示主进程,也可以称为父进程
 #注意:一个进程启动之后,系统会自动分配一个进程号
 print("父进程启动-%s" % (os.getpid()))

 #2.在父进程中创建子进程
 #语法:Process(target,args),target表示进程执行的任务,args表示所执行任务的参数,该参数为元组
 #2.1任务函数没有参数
 #注意:进程对象创建完成之后,必须手动启动
 #p1 = Process(target=run)
 # start函数会自动调用子进程的任务函数
 #p1.start()

 #2.2任务函数有参数
 p2 = Process(target=run1,args=(20,))
 p2.start()

 #父进程的任务
 while True:
     print("hello")
     sleep(1)

2.3父子进程的执行顺序

from  multiprocessing import  Process
from  time import  sleep
import  os

def run():
 print("子进程启动")

 sleep(3)

 print("子进程结束")

if __name__ == "__main__":
 print("父进程启动~~~~~")

 sleep(2)

 p = Process(target=run)

 p.start()

 #调用join函数必须在start之后
 p.join()  # AssertionError: can only join a started process

 print("父进程结束~~~~~")

 """
 结论;
     a.默认情况下,父进程结束之后子进程才会被启动
     b.子进程对象调用join函数完成合并,当子进程执行结束之后父进程才会结束
 """
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值