我的第一个python web开发框架(13)——工具函数包说明(四)

  string_helper.py是字符串操作包,主要对字符串进行检查、过滤和截取等处理。

  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全称,如&gt;
118         key=sz.group('name')#去除&;后entity,如&gt;为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
View Code

  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服务下才行进行测试操作,不能直接运行测试用例进行测试,大家可以先了解一下里面函数的功能。

  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
View Code

  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/

posted @ 2017-10-26 13:07  AllEmpty  阅读(5783)  评论(1编辑  收藏  举报