import datetime
now = datetime.datetime.now()#定义现在的时间
after = now + datetime.timedelta(3)print(after)#打印现在的时间加时间间隔3天,及3天后的时间print(datetime.datetime.strftime(after,"%Y-%m-%d %T"))#格式化间隔3天后的时间
after = now + datetime.timedelta(3,minutes=30)#定义时间为当前时间加3天30分钟print(datetime.datetime.strftime(after,"%Y-%m-%d %T"))#输出格式化后的时间
import re
str="devops_study 2023"
result = re.search('.',str)#匹配除换行符(\n)以外的单个任意字符.匹配一个则停止print(result)--<re.Match object; span=(0,1),match='d'>#span为所在的索引位,match为匹配内容
result = re.search("^devops",str)#匹配devops开头的内容
result = re.findall(pattern="^devops",string=stre)#匹配devops开头的内容,findall根据pattern的方式匹配字符串内容返回列表元素的结果,可以通过for循环取出
result = re.search("2023$",stre)#匹配2023结尾的内容
result = re.search("[_2]",stre)#匹配[]中的任意内容如果内容中存在_则停止匹配,返回当前匹配结果
result = re.search("[A-Z,0-9]",stre)#匹配[]中的任意内容如果内容中,A-Z命中后停止匹配
stre ="$00123"
result = re.search("[00$]",stre)#匹配[]中的任意内容如果内容,$为无效字符,哪个字符先匹配则停止
span=(0,1),match='$'
stre ='ab58abc'
result = re.search('[^ab]',stre)#^在中括号中是取反的意思,比如[^ab]匹配到不是 a、b中的任意一个其他字符.
3.2 特殊正则
result = re.search('5\w\w',stre)#匹配字符中包含5后面是俩个任意字符的内容----span=(2,5),match='58a'
stri ="嫦娥¥号"
result = re.search('嫦娥\W号',stri)
a = result.group()#group将结果进行截取,默认group0,返回整体print(a)----嫦娥¥号
stri ='联想 lenovo 2020\\'
result = re.search('\\\\',stri)#匹配俩个斜杠#因为正则表达式里匹配一个反斜杠必须是 '\\' ,而每个反斜杠在普通的 Python 字符串里都要写成 '\\' 。
stri ='联想 lenovo 2020\\'
result = re.search('[en]',stri)#查找e或n的某个字符,查到一个则停止
stri ='hello2020 hello'
result = re.search(r'\bhello\b',stri)#匹配单词边界,匹配hello前后各一个字符或不存在字符.后方多字符则不匹配.
result = re.search('(eno)',stri)#匹配eno组合的字符
3.3 拓展正则
.:匹配除换行符(\n)以外的单个任意字符
^:匹配整个字符串的开头
$:匹配整个字符串的结尾
[]:匹配中括号内字符中的任何一个 比如:[1a] 匹配到 1 或者 a
[-]:匹配连续的字符范围 比如 [0-9] 表示 0 到 9之间的任意一个数字
\w:匹配单个字母、数字、汉字或下划线
\d:匹配单个数字
\s:匹配单个任意的空白符
\b:匹配单词的开始或结束
*:对它前面的正则模式匹配0到任意次重复, 尽量多的匹配字符串。 | ab* 会匹配 'a', 'ab', 或者 'a'后面跟随任意个 'b'。a只能出现一次
+:对它前面的正则式匹配1到任意次重复。 | lv6+ 匹配 lv 后面跟随1个以上到任意个 '6',它不会匹配 'lv'。
?:对它前面的一个正则模式匹配0到1次重复。 | lv6? 匹配 lv 和 lv6,要么没有6要么出现1次
{m}:重复它前一个正则模式 m 次 a{2} 匹配 aa
{m,}:重复它前一个正则模式 m 次或 m 次以上 a{2,} 匹配 aa 或连续两个 a以上
{m, n}:重复前一个正则模式 m 到 n 次之间的任意一个都可以 a{2,5} 匹配连续2 个到 5 个之间的 a。如:'aa','aaa','aaaa','aaaaa'
3.4 python使用正则
3.4.1 常用方法
import re
"match"#只在整个字符串的起始位置进行匹配
string ="isinstance yangge enumerate www.qfedu.com 1997"
r = re.match('is\w+',string)#匹配is后面是任意字符出现1次到多次print(r)"search"#从整个字符串的开头找到最后,当第一个匹配成功后,就不再继续匹配。
r = re.search('a\w+',string)#查询字符串开头为a,后方为任意字符出现1-n次print(r)"findall"#搜索整个字符串,找到所有匹配成功的字符串,比把这些字符串放在一个列表中返回。
r = re.findall('a\w+',string)#查询字符串中所有组合为a+任意字符重复1-n的内容print(r)"sub"#把匹配成功的字符串,进行替换。
r = re.sub('a\w+',"哈哈哈",string,1)#查询a后方任意字符出现1-n次,替换为哈哈哈,针对str文本,替换1次print(r)"split"#以匹配到的字符进行分割,返回分割后的列表
r = re.split('a',string,1)#遇到a进行分割,分割一次print(r)"""使用多个界定符分割字符串"""
line ='asdf fjdk; afed, fjek,asdf, foo'
r = re.split(r'[;,\s]\s*',line)#r不专业字''号中的内容,遇到;、,、空格,空格后面是任意字符内容,进行分割print(r)#['asdf', 'fjdk', 'afed', 'fjek', 'asdf', 'foo']
3.4.2 分组
3.4.2.1 match
import re
"""==从已经成功匹配的内容中,再去把想要的取出来==""""match"
stre ='isinstance yangge enumerate www.qfedu.com 1997'
r = re.match("is(\w+)",stre)#此时匹配的是isinstance的长字符串,分组为instance内容
r = r.groups()#打印分组中的内容print(r)#('instance',)"""
group()返回类型为 字符串,表示返回整个匹配对象作为一个字符串
group(1)返回类型为 字符串,表示返回正则表达式的第1个( )匹配的对象,group(0)等同于group()返回整个匹配对象
groups()返回类型为元祖,表示返回正则表达式每个子组(每个())匹配的对象依次放进元祖里,如果正则表达式没有(),则返回空元祖()。
"""
3.4.2.2 search
import re
"search"
string ='isinstance yangge enumerate www.qfedu.com 1997'
r = re.search("is\w+\s(?P<name>y\w+e)", string)#匹配is打头后面为字母或特殊字符+空白符,命名分组,内容为y+任意字符出现1-n次+e结尾,分组名为nameprint(r.group())#返回整个匹配对象print(r.groups())#返回分组内容匹配的对象print(r.groupdict())#打印分组的信息为字典类型:{'name': 'yangge'}
3.4.2.3 findall && finditer
import re
"findall"
string ='isinstance yangge enumerate www.qfedu.com 1997'
r = re.findall("a(?P<name>\w+)", string)#findall,查找字符串中所有满足条件的字符,返回list#匹配a打头,分组名称为name,正则内容为任意字符出现1-n次print(r)#输出为字符按包含a,中的后面字符出现1-n次的内容
r = re.findall("a(\w+)",string)print(r)#findall之返回分组内的内容,不返回前方的字符匹配内容
haystack ="sadbutsad"
needle ="sad"import re
f = re.finditer(needle,haystack)#finditer返回非重叠字符的mathch对象。多次匹配for i in f:print(i)#返回math对象print(i.span())#返回下标
3.4.2.4 split
import re
"findall"
string ='isinstance yangge enumerate www.qfedu.com 1997'
r = re.split("(an)",string)#字符串中匹配到an就进行分割print(r)
tag ='value="1997/07/01"'
s = re.sub(r'(value="\d{4})/(\d{2})/(\d{2})"',r'\1年\2月\3日"', tag)#sub:匹配正则内容进行替换,数字出现4次,2次,2次,替换为分组1+年,分组2+年,分组3+年.对tagstr进行操作print(s)
3.5 常用正则
"常用正则""邮箱"import re
context ="shark123@qq.com,shark123@163.com"
pattern = re.compile(r"[a-zA-Z0-9_-]+@[a-zA-Z0-9]+\.[a-zA-Z]{2,3}")#re.compile可以提前编译正则表达式(定义正则匹配规则).内容为:a-9加特殊字符集合开头,@a-9+.a-Z出现2-3次,因为正常邮箱结尾都为2-3次cn、com
result = pattern.findall(context)#re.findall可以搜索多种匹配模式(全文匹配)print(result)"手机号"
conetxt ="""
白日依19989881888山尽,黄河入45645546468798978海流。
欲穷12345千里目,更上15619292345一层楼。
"""import re
pattern =r"(1\d)\d{7}(\d{2})"#pattern方法为给开头1\d进行分组(俩位数),即开头的俩个数字(1\d).中间位数为7位,(\d{2})即尾数为2个数字作为第二个分组print(re.sub(pattern,r"\1*****\2",conetxt))#\1引用正则中的第一个分组,也就是1开头,结尾为分组内容2
new_pattern =r"1\d{10}"#提取电话号码为1开头任意数字出现10次
result = re.findall(new_pattern,conetxt)for i in result:print(f"提取到的电话号码为:{i}")"IP地址"
s ='lenovo 192.137.1.336 shark 192.168.1.130 255.255.255.255 qf 192.168.1.138 lenovo,34.106.23.123,8.8.8.8'
pattern =r'(?<![.\d])(?:2[0-3]\d|1\d\d|[1-9]\d{0,1})\.(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d{0,1})\.){2}?(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d{0,1})(?![.\d])'
result = re.findall(pattern,s)print(result)"贪婪和非贪婪"print(re.findall('\d+\.?\d*',"asdfasdf123as1.13dfa12adsf1asdf3"))#['123', '1.13', '12', '1', '3']# 匹配所有包含小数在内的数字。# 查询数字出现1-n次,.出现0-1次数字出现1-n次print(re.findall('a.*b','a1b22222222b'))#['a1b22222222b']##.*默认为贪婪匹配,匹配a后面除换行符的任意单个字符.b为尾部print(re.findall('a.*?b','a1b22222222b'))#['a1b']#.*?为非贪婪匹配:推荐使用#a后方单个任意字符,出现0或1次,则中间的字符只能出现1次print(re.findall('a.*?b','ab,asd,asdab,asb'))#['ab', 'asd,asdab', 'asb']#a.*?b:a打头换行符除外任意单个字符,出现0-1次.只能匹配到a-b或者ab