我的第一个python web开发框架(13)——工具函数包说明(四)
string_helper.py是字符串操作包,主要对字符串进行检查、过滤和截取等处理。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #!/usr/bin/evn python 2 # coding=utf-8 3 4 import re 5 6 7 def check_string(text, pattern): 8 """ 9 检查字符串是否符合指定规则 10 :param text: 需要检查的字符串 11 :param pattern: 正式表达式,如:'^[a-zA-Z]+$' 12 :return: 含有指定字符时返回真,否则为假 13 """ 14 match = re.search(pattern, text) 15 if match: 16 return True 17 else: 18 return False 19 20 21 def is_email(text): 22 """ 23 验证字符串是否是email 24 :param text: 需要检查的字符串 25 :return: 符合返回True,不符合返回False 26 """ 27 return check_string(text, '[^\._-][\w\.-]+@(?:[A-Za-z0-9]+\.)+[A-Za-z]+$') 28 29 30 def is_phone(text): 31 """ 32 验证字符串是否是固定电话 33 :param text: 需要检查的字符串 34 :return: 符合返回True,不符合返回False 35 """ 36 return check_string(text, '\(?0\d{2,3}[) -]?\d{7,8}$') 37 38 39 def is_mobile(text): 40 """ 41 验证字符串是否是手机号码 42 :param text: 需要检查的字符串 43 :return: 符合返回True,不符合返回False 44 """ 45 return check_string(text, '^1[3578]\d{9}$|^147\d{8}$') 46 47 48 def is_letters(text): 49 """ 50 验证字符串是否全是字母 51 :param text: 需要检查的字符串 52 :return: 符合返回True,不符合返回False 53 """ 54 return check_string(text, '^[a-zA-Z]+$') 55 56 57 def is_idcard(text): 58 """ 59 验证字符串是否是身份证号码 60 :param text: 需要检查的字符串 61 :return: 格式正确返回True,错误返回False 62 """ 63 ic = IdentityCard() 64 return ic.check(text.upper()) 65 66 67 def filter_str(text, filter='\||<|>|&|%|~|\^|;|\''): 68 """ 69 滤掉字符串 70 :param text: 需要过滤的字符串 71 :param filter: 过滤内容(正则表达式) 72 :return: 去除特殊字符后的字符串 73 """ 74 if text: 75 return re.subn(filter, '', text)[0] 76 else: 77 return '' 78 79 def filter_tags(htmlstr): 80 """ 81 过滤HTML中的标签 82 :param htmlstr: 要过滤的内容 83 :return: 84 """ 85 re_cdata=re.compile('//<!\[CDATA\[[^>]*//\]\]>',re.I) #匹配CDATA 86 re_script=re.compile('<\s*script[^>]*>[^<]*<\s*/\s*script\s*>',re.I)#Script 87 re_style=re.compile('<\s*style[^>]*>[^<]*<\s*/\s*style\s*>',re.I)#style 88 re_br=re.compile('<br\s*?/?>')#处理换行 89 re_h=re.compile('</?\w+[^>]*>')#HTML标签 90 re_comment=re.compile('<!--[^>]*-->')#HTML注释 91 s=re_cdata.sub('',htmlstr)#去掉CDATA 92 s=re_script.sub('',s) #去掉SCRIPT 93 s=re_style.sub('',s)#去掉style 94 s=re_br.sub('\n',s)#将br转换为换行 95 s=re_h.sub('',s) #去掉HTML 标签 96 s=re_comment.sub('',s)#去掉HTML注释 97 #去掉多余的空行 98 blank_line=re.compile('\n+') 99 s=blank_line.sub('\n',s) 100 s=replaceCharEntity(s)#替换实体 101 return s 102 103 def replaceCharEntity(htmlstr): 104 """ 105 替换常用HTML字符 106 :param htmlstr: 要替换的字符 107 :return: 108 """ 109 CHAR_ENTITIES={'nbsp':' ','160':' ', 110 'lt':'<','60':'<', 111 'gt':'>','62':'>', 112 'amp':'&','38':'&', 113 'quot':'"','34':'"',} 114 re_charEntity=re.compile(r'&#?(?P<name>\w+);') 115 sz=re_charEntity.search(htmlstr) 116 while sz: 117 entity=sz.group()#entity全称,如> 118 key=sz.group('name')#去除&;后entity,如>为gt 119 try: 120 htmlstr=re_charEntity.sub(CHAR_ENTITIES[key],htmlstr,1) 121 sz=re_charEntity.search(htmlstr) 122 except KeyError: 123 #以空串代替 124 htmlstr=re_charEntity.sub('',htmlstr,1) 125 sz=re_charEntity.search(htmlstr) 126 return htmlstr 127 128 129 def string(text, is_return_null=False): 130 """ 131 sql字符串拼接专用函数 132 会在字符串两边添加'单撇号,用于生成数据库sql语句 133 :param text: 需要添加'的字符串 134 :param is_return_null: 是否返回null,是的话在字符串为空时返回null,否则返回'' 135 :return: 136 """ 137 if not text is None and text != '': 138 return "'" + str(text) + "'" 139 elif not is_return_null: 140 return "''" 141 else: 142 return "null" 143 144 145 def cut_str(text, length): 146 """ 147 将字符串截取指定长度 148 :param text: 需要进行截取的字符串 149 :param length: 字符串保留的长度 150 :return: 151 """ 152 if not text or not isinstance(text, str): 153 return text 154 tem = '' 155 try: 156 tem = text.decode('utf8') 157 except: 158 pass 159 if not tem or tem == '': 160 try: 161 tem = text[0:length] 162 except: 163 tem = text 164 return tem[0:length] 165 166 167 class IdentityCard: 168 """身份证号码验证类""" 169 170 def __init__(self): 171 self.__Wi = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2] 172 self.__Ti = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'] 173 174 def calculate(self, code): 175 """计算校验位""" 176 sum = 0 177 for i in range(17): 178 sum += int(code[i]) * self.__Wi[i] 179 return self.__Ti[sum % 11] 180 181 def check(self, code): 182 """检查输入的号码是否正确""" 183 184 if (len(code) != 18): 185 return False 186 if self.calculate(code) != code[17]: 187 return False 188 189 return True
check_string()函数主要是用来检查字符串是否符合指定规则用的,它被is_开头的各个函数所调用。is_开头的几个函数怎么使用,请看测试用例。
#!/usr/bin/evn python # coding=utf-8 import unittest from common import string_helper class StringHelperTest(unittest.TestCase): """字符串操作包测试类""" def setUp(self): """初始化测试环境""" print('------ini------') def tearDown(self): """清理测试环境""" print('------clear------') def test_is_email(self): self.assertEqual(string_helper.is_email('aaaaa'), False) self.assertEqual(string_helper.is_email('aaaa@xxx.com'), True) self.assertEqual(string_helper.is_email('xxx@xxx.com.xx'), True) def test_is_phone(self): self.assertEqual(string_helper.is_phone('aaaaa'), False) self.assertEqual(string_helper.is_phone('12345678'), False) self.assertEqual(string_helper.is_phone('01012345678'), True) self.assertEqual(string_helper.is_phone('010-123456'), False) self.assertEqual(string_helper.is_phone('010-12345678'), True) self.assertEqual(string_helper.is_phone('010 12345678'), True) self.assertEqual(string_helper.is_phone('0757 12345678'), True) def test_is_mobile(self): self.assertEqual(string_helper.is_mobile('aaaaa'), False) self.assertEqual(string_helper.is_mobile('123456789'), False) self.assertEqual(string_helper.is_mobile('13012345678'), True) self.assertEqual(string_helper.is_mobile('14012345678'), False) def test_is_letters(self): self.assertEqual(string_helper.is_letters('123456'), False) self.assertEqual(string_helper.is_letters('1ds2f12sdf'), False) self.assertEqual(string_helper.is_letters('absbdsf'), True) self.assertEqual(string_helper.is_letters('ADdfFSds'), True) def test_is_idcard(self): self.assertEqual(string_helper.is_idcard('123456789'), False) self.assertEqual(string_helper.is_idcard('aaaaaaaaa'), False) self.assertEqual(string_helper.is_idcard('340223190008210470'), False) self.assertEqual(string_helper.is_idcard('34022319000821047X'), True) if __name__ == '__main__': unittest.main()
filter_str()函数用来将指定的特殊字符全部过滤掉
def test_filter_str(self): print(string_helper.filter_str('aaa')) print(string_helper.filter_str('aaa<>&\'')) print(string_helper.filter_str('aaa<|>|&|%|~|^|;|\''))
执行结果:
------ini------
aaa
aaa
aaa
------clear------
filter_tags函数将代码上的全部html标签过滤掉(网上找到来的代码)
def test_filter_tags(self): print(string_helper.filter_tags('<html><body><b>aaa</b></body></html>'))
执行结果:
------ini------
aaa
------clear------
string()函数主要用于拼接sql语句用的,用于在字符串的两边添加 ' 这个单撇号,如果is_return_null这个参数为True时,输入内容为空则返回null字符
def test_string(self): print(string_helper.string(-1)) print(string_helper.string({'test': 'abc'})) print(string_helper.string('')) print(string_helper.string('aaa')) print(string_helper.string('', True))
执行结果:(使用print打印到控制台的结果,字符串不输出""双引号,实际上存储到变量中时,下面内容都会加上双引号)
------ini------ '-1' '{'test': 'abc'}' '' 'aaa' null ------clear------
cut_str()函数会将输入的字符串按指定长度截取
def test_cut_str(self): print(string_helper.cut_str('', 5)) print(string_helper.cut_str('aaa', 5)) print(string_helper.cut_str('将字符串截取指定长度', 5)) print(string_helper.cut_str('aa将字符串截取指定长度', 5))
执行结果:
------ini------
aaa
将字符串截
aa将字符
------clear------
verify_helper.py是验证码生成包,调用比较简单,这里就不再详细说明,到后面章节会有详细例子。
web_helper.py是web操作包,主要是对web服务进行相关处理。它需要启动web服务后基于web服务下才行进行测试操作,不能直接运行测试用例进行测试,大家可以先了解一下里面函数的功能。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #!/usr/bin/evn python 2 # coding=utf-8 3 4 import json 5 import re 6 import urllib.parse 7 from bottle import response, HTTPResponse, request 8 from common import json_helper 9 10 11 def get_ip(): 12 """获取当前客户端ip""" 13 try: 14 ip = request.remote_addr 15 except: 16 ip = '' 17 if not ip: 18 try: 19 ip = request.environ.get('REMOTE_ADDR') 20 except: 21 pass 22 return ip 23 24 25 def get_session(): 26 """获取当前用户session""" 27 return request.environ.get('beaker.session') 28 29 30 def return_msg(state, msg, data={}): 31 """ 32 接口输出数据到客户端 33 :param state: 状态码(公共参数,-1=出错,0=正常) 34 :param msg: 说明信息(公共参数) 35 :param data: 数据字典 36 :return: 返回组合后的json字符串 37 """ 38 msg = { 39 "state": state, 40 "msg": msg, 41 "data": data 42 } 43 # 将字典转为字符串输出 44 message = json.dumps(msg, cls=json_helper.CJsonEncoder) 45 return message 46 47 48 def return_raise(msg=''): 49 """ 50 直接终止程序,返回结果给客户端 51 修改bottle的异常状态码和异常返回body内容 52 :param msg: 输出内容 53 :return: 输出字符串 54 """ 55 res = response.copy(cls=HTTPResponse) 56 res.status = 200 57 res.body = str(msg) 58 raise res 59 60 61 def get_form(args_name, msg, is_strip=True, lenght=0, is_check_null=True, notify_msg='', is_check_special_char=True): 62 """ 63 获取客户端Form方式提交的参数值 64 :param args_name: 参数名 65 :param msg: 参数中文名称 66 :param is_strip: 字符串两端是否自动去除空格 67 :param lenght: 参数长度最大限制,0为不限制 68 :param is_check_null: 是否要求进行非空检测,True:当参数值为空时,返回错误提示客户端不能为空 69 :param notify_msg: 非必填项,当参数值为空时,默认返回“xxx 不允许为空”这个提示,如果这个变量有值,则直接返回这个变量值,即定制好的错误提示 70 :param is_check_special_char: 判断参数值是否含有特殊字符,True=默认会对特殊字符进行判断,False=不做判断处理,需要手动对接收参数值进行过滤处理,去除危险字符 71 :return: 返回处理后的参数 72 """ 73 args_value = '' 74 if request.method.upper() in ('POST', 'PUT', 'DELETE'): 75 try: 76 if request.json: 77 args_value = str(request.json.get(args_name, '')).strip() 78 else: 79 args_value = str(request.forms.get(args_name, '')).strip() 80 except: 81 args_value = str(request.forms.get(args_name, '')).strip() 82 if not args_value: 83 args_value = str(request.POST.get(args_name, '')).strip() 84 85 return __request_handle(args_value, msg, is_strip, lenght, is_check_null, notify_msg, is_check_special_char) 86 87 88 def get_query(args_name, msg, is_strip=True, lenght=0, is_check_null=True, notify_msg='', is_check_special_char=True): 89 """ 90 获取客户端Get方式提交的参数值 91 :param args_name: 参数名 92 :param msg: 参数中文名称 93 :param is_strip: 字符串两端是否自动去除空格 94 :param lenght: 参数长度最大限制,0为不限制 95 :param is_check_null: 是否要求进行非空检测,True:当参数值为空时,返回错误提示客户端不能为空 96 :param notify_msg: 非必填项,当参数值为空时,默认返回“xxx 不允许为空”这个提示,如果这个变量有值,则直接返回这个变量值,即定制好的错误提示 97 :param is_check_special_char: 判断参数值是否含有特殊字符,True=默认会对特殊字符进行判断,False=不做判断处理,需要手动对接收参数值进行过滤处理,去除危险字符 98 :return: 返回处理后的参数 99 """ 100 return __request_handle(__get(args_name), msg, is_strip, lenght, is_check_null, notify_msg, is_check_special_char) 101 102 103 def __get(args_name): 104 """ 105 从get请求中提取请求值(直接使用python的GET获取参数时,有时转换编码时会出现乱码,所以还是直接采用截取后直接转码比较好) 106 例如:http://127.0.0.1:81/manage/manager/?page=0&rows=20&sidx=id&sord=desc&name=%E5%BC%A0%E4%B8%89 107 :param args_name: 要取值的参数名:name 108 :return: 截取的编码值:%E5%BC%A0%E4%B8%89 109 """ 110 get = '?' + request.query_string 111 start_index = get.find('&' + args_name + '=') 112 if start_index == -1: 113 start_index = get.find('?' + args_name + '=') 114 if start_index == -1: 115 return '' 116 end_index = get.find('&', start_index + 1) 117 if end_index == -1: 118 return get[start_index + len(args_name + '=') + 1:] 119 else: 120 return get[start_index + len(args_name + '=') + 1:end_index] 121 122 123 def __request_handle(args_value, msg, is_strip, lenght, is_check_null, notify_msg, is_check_special_char): 124 """ 125 对客户端提交的参数进行各种判断与处理 126 :param args_value: 参数值 127 :param msg: 参数中文名称 128 :param is_strip: 字符串两端是否自动去除空格 129 :param lenght: 参数长度最大限制,0为不限制 130 :param is_check_null: 是否要求进行非空检测,True:当参数值为空时,返回错误提示客户端不能为空 131 :param notify_msg: 非必填项,当参数值为空时,默认返回“xxx 不允许为空”这个提示,如果这个变量有值,则直接返回这个变量值,即定制好的错误提示 132 :param is_check_special_char: 判断参数值是否含有特殊字符,True=默认会对特殊字符进行判断,False=不做判断处理,需要手动对接收参数值进行过滤处理,去除危险字符 133 :return: 返回处理后的参数 134 """ 135 # 如果参数为空,则返回该参数不允许为空的json串给前端 136 if is_check_null and not args_value: 137 if notify_msg: 138 return_raise(return_msg(-1, notify_msg)) 139 else: 140 return_raise(return_msg(-1, "%s 不允许为空" % msg)) 141 elif not args_value: 142 return args_value 143 144 # 把utf-8的url编码解码成中文字符 145 try: 146 args_value = urllib.parse.unquote(args_value) 147 except: 148 pass 149 150 # 替换特殊的空字符 151 args_value = args_value.replace(u'\xa0', u'') 152 # 是否字符串两端去空格 153 if is_strip: 154 args_value = args_value.strip() 155 # 判断是否超出指定长度 156 if lenght > 0 and len(args_value) > lenght: 157 return_raise(return_msg(-1, "%s 超出 %s 个字符" % (msg, lenght))) 158 159 # 如果参数含有特殊字符,则返回该参数不允许有特殊字符的json串给前端 160 if is_check_special_char: 161 re_result = re.search('\||<|>|&|%|~|\^|;|\'', args_value) 162 if re_result: 163 return_raise(return_msg(-1, "%s 含有特殊字符,请重新输入" % msg)) 164 return args_value
get_ip():获取当前客户端ip地址
get_session():获取当前客户的session
return_msg():生成统一的返回给客户端的内容(json格式)。输出内容有state:状态码,一般使用-1表示出现错误,0表示正常,可以根据需要进行修改或添加更多的状态码;msg:状态文说明,出错时返回出错内容提示;data:需要返回的其他内容全部会放在这里。
return_raise():当调用这个函数时,会直接终于代码的执行,直接将结果输出到客户端。
get_form():获取客户端Form方式提交的参数值
get_query():获取客户端Get方式提交的参数值
版权声明:本文原创发表于 博客园,作者为 AllEmpty 本文欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则视为侵权。
python开发QQ群:669058475(本群已满)、733466321(可以加2群) 作者博客:http://www.cnblogs.com/EmptyFS/