首页/文章/ 详情

正则表达式

3月前浏览1080

字符串是编程时涉及到的最多的一种数据结构,对字符串进行操作的需求几乎无处不在。比如判断一个字符串是否是合法的Email地址,虽然可以编程提取@前后的子串,再分别判断是否是单词和域名,但这样做不但麻烦,而且代码难以复用。

正则表达式是一种用来匹配字符串的强有力的武器。它的设计思想是用一种描述性的语言来给字符串定义一个规则,凡是符合规则的字符串,我们就认为它“匹配”了,否则,该字符串就是不合法的。

所以我们判断一个字符串是否是合法的Email的方法是:

  1. 创建一个匹配Email的正则表达式;

  2. 用该正则表达式去匹配用户的输入来判断是否合法。

因为正则表达式也是用字符串表示的,所以,我们要首先了解如何用字符来描述字符。

在正则表达式中,如果直接给出字符,就是精确匹配。用\d可以匹配一个数字,\w可以匹配一个字母或数字,所以:

  • '00\d'可以匹配'007',但无法匹配'00A'

  • '\d\d\d'可以匹配'010'

  • '\w\w\d'可以匹配'py3'

.可以匹配任意字符,所以:

  • 'py.'可以匹配'pyc''pyo''py!'等等。

要匹配变长的字符,在正则表达式中,用*表示任意个字符(包括0个),用+表示至少一个字符,用?表示0个或1个字符,用{n}表示n个字符,用{n,m}表示n-m个字符:

来看一个复杂的例子:\d{3}\s+\d{3,8}

我们来从左到右解读一下:

  1. \d{3}表示匹配3个数字,例如'010'

  2. \s可以匹配一个空格(也包括Tab等空白符),所以\s+表示至少有一个空格,例如匹配' '' '等;

  3. \d{3,8}表示3-8个数字,例如'1234567'

综合起来,上面的正则表达式可以匹配以任意个空格隔开的带区号的电话号码。

如果要匹配'010-12345'这样的号码呢?由于'-'是特殊字符,在正则表达式中,要用'\'转义,所以,上面的正则是\d{3}\-\d{3,8}

但是,仍然无法匹配'010 - 12345',因为带有空格。所以我们需要更复杂的匹配方式。

进阶

要做更精确地匹配,可以用[]表示范围,比如:

  • [0-9a-zA-Z\_]可以匹配一个数字、字母或者下划线;

  • [0-9a-zA-Z\_]+可以匹配至少由一个数字、字母或者下划线组成的字符串,比如'a100''0_Z''Py3000'等等;

  • [a-zA-Z\_][0-9a-zA-Z\_]*可以匹配由字母或下划线开头,后接任意个由一个数字、字母或者下划线组成的字符串,也就是Python合法的变量;

  • [a-zA-Z\_][0-9a-zA-Z\_]{0, 19}更精确地限制了变量的长度是1-20个字符(前面1个字符+后面最多19个字符)。

A|B可以匹配A或B,所以(P|p)ython可以匹配'Python'或者'python'

^表示行的开头,^\d表示必须以数字开头。

$表示行的结束,\d$表示必须以数字结束。

你可能注意到了,py也可以匹配'python',但是加上^py$就变成了整行匹配,就只能匹配'py'了。

来源:灵境地平线
python
著作权归作者所有,欢迎分享,未经许可,不得转载
首次发布时间:2024-08-04
最近编辑:3月前
周末--电磁仿真
博士 微波电磁波
获赞 23粉丝 21文章 163课程 0
点赞
收藏
作者推荐

python3+oauth2发微博遇到的问题

找了一些使用微博pythonsdk的代码,但是都是python2.7版本,pipinstallsinaweibopy命令不能执行,因为python版本更新到3.7找到了一个经网友修改后的可执行的代码,按提示将网址复制到浏览器得到所需的code但是输入运行后出先如下图所示的问题。代码附上,以后慢慢修改#!/usr/bin/envpython#-*-coding:utf-8-*-__version__='1.04'__author__='LiaoXuefeng(askxuefeng@gmail.com)'__publish__='http://www.cnblogs.com/txw1958/''''Python3clientSDKforsinaweiboAPIusingOAuth2.'''try:importjsonexceptImportError:importsimplejsonasjsonimporttimeimporturllib.requestimportloggingdef_obj_hook(pairs):'''convertjsonobjecttopythonobject.'''o=JsonObject()fork,vinpairs.items():o[str(k)]=vreturnoclassAPIError(Exception):'''raiseAPIErrorifgotfailedjsonmessage.'''def__init__(self,error_code,error,request):self.error_code=error_codeself.error=errorself.request=requestException.__init__(self,error)def__str__(self):return'APIError:%s:%s,request:%s'%(self.error_code,self.error,self.request)classJsonObject(dict):'''generaljsonobjectthatcanbindanyfieldsbutalsoactasadict.'''def__getattr__(self,attr):returnself[attr]def__setattr__(self,attr,value):self[attr]=valuedef_encode_params(**kw):'''Encodeparameters.'''args=[]fork,vinkw.items():qv=v.encode('utf-8')ifisinstance(v,str)elsestr(v)args.append('%s=%s'%(k,urllib.parse.quote(qv)))return'&'.join(args)def_encode_multipart(**kw):'''Buildamultipart/form-databodywithgeneratedrandomboundary.'''boundary='----------%s'%hex(int(time.time()*1000))data=[]fork,vinkw.items():data.append('--%s'%boundary)ifhasattr(v,'read'):filename=getattr(v,'name','')n=filename.rfind('.')ext=filename[n:].lower()ifn!=(-1)else""content=v.read()content=content.decode('ISO-8859-1')data.append('Content-Disposition:form-data;name="%s";filename="hidden"'%k)data.append('Content-Length:%d'%len(content))data.append('Content-Type:%s\r\n'%_guess_content_type(ext))data.append(content)else:data.append('Content-Disposition:form-data;name="%s"\r\n'%k)data.append(vifisinstance(v,str)elsev.decode('utf-8'))data.append('--%s--\r\n'%boundary)return'\r\n'.join(data),boundary_CONTENT_TYPES={'.png':'image/png','.gif':'image/gif','.jpg':'image/jpeg','.jpeg':'image/jpeg','.jpe':'image/jpeg'}def_guess_content_type(ext):return_CONTENT_TYPES.get(ext,'application/octet-stream')_HTTP_GET=0_HTTP_POST=1_HTTP_UPLOAD=2def_http_get(url,authorization=None,**kw):logging.info('GET%s'%url)return_http_call(url,_HTTP_GET,authorization,**kw)def_http_post(url,authorization=None,**kw):logging.info('POST%s'%url)return_http_call(url,_HTTP_POST,authorization,**kw)def_http_upload(url,authorization=None,**kw):logging.info('MULTIPARTPOST%s'%url)return_http_call(url,_HTTP_UPLOAD,authorization,**kw)def_http_call(url,method,authorization,**kw):'''sendanhttprequestandexpecttoreturnajsonobjectifnoerror.'''params=Noneboundary=Noneifmethod==_HTTP_UPLOAD:params,boundary=_encode_multipart(**kw)else:params=_encode_params(**kw)http_url='%s?%s'%(url,params)ifmethod==_HTTP_GETelseurlhttp_body=Noneifmethod==_HTTP_GETelseparams.encode(encoding='utf-8')req=urllib.request.Request(http_url,data=http_body)ifauthorization:req.add_header('Authorization','OAuth2%s'%authorization)ifboundary:req.add_header('Content-Type','multipart/form-data;boundary=%s'%boundary)resp=urllib.request.urlopen(req)body=resp.read().decode("utf-8")r=json.loads(body,object_hook=_obj_hook)if'error_code'inr:raiseAPIError(r.error_code,r['error_code'],r['request'])returnrclassHttpObject(object):def__init__(self,client,method):self.client=clientself.method=methoddef__getattr__(self,attr):defwrap(**kw):ifself.client.is_expires():raiseAPIError('21327','expired_token',attr)return_http_call('%s%s.json'%(self.client.api_url,attr.replace('__','/')),self.method,self.client.access_token,**kw)returnwrapclassAPIClient(object):'''APIclientusingsynchronizedinvocation.'''def__init__(self,app_key,app_secret,redirect_uri=None,response_type='code',domain='api.weibo.com',version='2'):self.client_id=app_keyself.client_secret=app_secretself.redirect_uri=redirect_uriself.response_type=response_typeself.auth_url='https://%s/oauth2/'%domainself.api_url='https://%s/%s/'%(domain,version)self.access_token=Noneself.expires=0.0self.get=HttpObject(self,_HTTP_GET)self.post=HttpObject(self,_HTTP_POST)self.upload=HttpObject(self,_HTTP_UPLOAD)defset_access_token(self,access_token,expires_in):self.access_token=str(access_token)self.expires=float(expires_in)defget_authorize_url(self,redirect_uri=None,display='default'):'''returntheauthroizeurlthatshouldberedirect.'''redirect=redirect_uriifredirect_urielseself.redirect_uriifnotredirect:raiseAPIError('21305','Parameterabsent:redirect_uri','OAuth2request')return'%s%s?%s'%(self.auth_url,'authorize',\_encode_params(client_id=self.client_id,\response_type='code',\display=display,\redirect_uri=redirect))defrequest_access_token(self,code,redirect_uri=None):'''returnaccesstokenasobject:{"access_token":"your-access-token","expires_in":12345678},expires_inisstandardunix-epoch-time'''redirect=redirect_uriifredirect_urielseself.redirect_uriifnotredirect:raiseAPIError('21305','Parameterabsent:redirect_uri','OAuth2request')r=_http_post('%s%s'%(self.auth_url,'access_token'),\client_id=self.client_id,\client_secret=self.client_secret,\redirect_uri=redirect,\code=code,grant_type='authorization_code')r.expires_in+=int(time.time())returnrdefis_expires(self):returnnotself.access_tokenortime.time()>self.expiresdef__getattr__(self,attr):returngetattr(self.get,attr)defmain():try:#step1定义appkey,appsecret,回调地址:APP_KEY="525566084"APP_SECRET="98e8559d04d5bfd168322d4ecfd014fb"CALLBACK_URL='https://api.weibo.com/oauth2/default.html'#step2引导用户到授权地址client=APIClient(app_key=APP_KEY,app_secret=APP_SECRET,redirect_uri=CALLBACK_URL)print(client.get_authorize_url())#step3换取AccessToken#将上面的地址复制到浏览器中运行,输入账号密码授权,新的网址里面就有coder=client.request_access_token(input("Inputcode:"))#输入授权地址中获得的CODEclient.set_access_token(r.access_token,r.expires_in)##此时获取到access_token和expires_in应该保存下来,因为有一个有效期,如果短时间需要多次发微博,可以重复使用,而不需要每次获取。##step4使用获得的OAuth2.0AccessToken调用APIprint(client.get.account__get_uid())print(client.post.statuses__update(status='测试Python3+OAuth2.0发微博'+str(time.time())))#print(client.upload.statuses__upload(status='测试Python3OAuth2.0带图片发微博'+str(time.time()),pic=open('test.png','rb')))exceptExceptionaspyOauth2Error:print(pyOauth2Error)if__name__=='__main__':main()来源:灵境地平线

未登录
还没有评论
课程
培训
服务
行家
VIP会员 学习 福利任务 兑换礼品
下载APP
联系我们
帮助与反馈