Squashed 'paste-framework/' content from commit 34e8684
git-subtree-dir: paste-framework git-subtree-split: 34e8684c4bc3cebbe177509f42ab4ef5b5425a7a
This commit is contained in:
@@ -0,0 +1,218 @@
|
||||
import datetime
|
||||
import gzip
|
||||
import io
|
||||
import re
|
||||
from typing import List
|
||||
from urllib.parse import quote
|
||||
|
||||
|
||||
def str_q_count(ustring):
|
||||
"""
|
||||
汉字加全角字符数量。
|
||||
|
||||
:param ustring: 待扫描文本
|
||||
:return: 全角字符数量
|
||||
"""
|
||||
count = 0
|
||||
for uchar in ustring:
|
||||
inside_code = ord(uchar)
|
||||
if '\u4e00' <= uchar <= '\u9fff' or 65281 <= inside_code <= 65374:
|
||||
count += 1
|
||||
return count
|
||||
|
||||
|
||||
def str_q2b(ustring):
|
||||
"""
|
||||
全角转半角。
|
||||
|
||||
:param ustring: 待转换文本
|
||||
:return: 转换后的文本
|
||||
"""
|
||||
r_str = ""
|
||||
for uchar in ustring:
|
||||
inside_code = ord(uchar)
|
||||
if inside_code == 12288:
|
||||
# 全角空格直接转换
|
||||
inside_code = 32
|
||||
elif 65281 <= inside_code <= 65374:
|
||||
# 全角字符(除空格)根据关系转化
|
||||
inside_code -= 65248
|
||||
r_str += chr(inside_code)
|
||||
return r_str
|
||||
|
||||
|
||||
def str_b2q(ustring):
|
||||
"""
|
||||
半角转全角。
|
||||
|
||||
:param ustring: 待转换文本
|
||||
:return: 转换后的文本
|
||||
"""
|
||||
r_str = ""
|
||||
for uchar in ustring:
|
||||
inside_code = ord(uchar)
|
||||
if inside_code == 32:
|
||||
# 半角空格直接转化
|
||||
inside_code = 12288
|
||||
elif 32 <= inside_code <= 126:
|
||||
# 半角字符(除空格)根据关系转化
|
||||
inside_code += 65248
|
||||
r_str += chr(inside_code)
|
||||
return r_str
|
||||
|
||||
|
||||
def str_gzip(data: str):
|
||||
"""
|
||||
创建gzip压缩数据。
|
||||
|
||||
:param data: 待压缩的数据
|
||||
"""
|
||||
buffer = io.BytesIO()
|
||||
with gzip.GzipFile(fileobj=buffer, mode='w') as f:
|
||||
f.write(data.encode('utf-8'))
|
||||
_compressed_data = buffer.getvalue()
|
||||
return _compressed_data
|
||||
|
||||
|
||||
def is_contains_chinese(text, length: int = None):
|
||||
"""
|
||||
检查字符串中是否包含中文字符。
|
||||
|
||||
:param text: 要检查的字符串
|
||||
:param length: 可选参数,要求中文字符的最小数量
|
||||
:return: 如果包含中文字符返回True,否则返回False
|
||||
"""
|
||||
chinese_chars = [char for char in text if '\u4e00' <= char <= '\u9fff']
|
||||
|
||||
if not chinese_chars:
|
||||
# 如果没有中文字符
|
||||
return False
|
||||
|
||||
if length is not None:
|
||||
# 如果指定了length参数
|
||||
return len(chinese_chars) >= length
|
||||
|
||||
return True # 默认情况,只要包含中文就返回True
|
||||
|
||||
|
||||
def is_valid_id_number(id_str):
|
||||
"""
|
||||
检查字符串是否符合中国居民身份证号码格式。
|
||||
|
||||
支持15位和18位身份证号码,包括校验位验证
|
||||
:param id_str: 要检查的字符串
|
||||
:return: 如果符合格式返回True,否则返回False
|
||||
"""
|
||||
# 正则表达式匹配
|
||||
pattern = r'^[1-9]\d{5}(19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$'
|
||||
if not re.match(pattern, id_str):
|
||||
return False
|
||||
|
||||
# 如果是15位身份证,直接返回True(15位不包含校验位)
|
||||
if len(id_str) == 15:
|
||||
return True
|
||||
|
||||
# 18位身份证校验位验证
|
||||
# 权重系数
|
||||
weight = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
|
||||
# 校验码对应值
|
||||
validate = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2']
|
||||
|
||||
# 计算校验位
|
||||
sum_val = 0
|
||||
for i in range(17):
|
||||
sum_val += int(id_str[i]) * weight[i]
|
||||
|
||||
mod_val = sum_val % 11
|
||||
if validate[mod_val].upper() != id_str[17].upper():
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def is_valid_phone_number(phone_str):
|
||||
"""
|
||||
验证是否是中国大陆合法的手机号码。
|
||||
|
||||
:param phone_str: 要检查的字符串
|
||||
:return: 如果是合法手机号返回True,否则返回False
|
||||
"""
|
||||
# 2023年中国大陆手机号正则表达式
|
||||
pattern = r'^1(3[0-9]|4[5-9]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9])\d{8}$'
|
||||
|
||||
return bool(re.fullmatch(pattern, phone_str))
|
||||
|
||||
|
||||
def is_valid_postcode(postcode):
|
||||
"""
|
||||
验证中国邮政编码是否合法
|
||||
:param postcode: 要验证的邮编字符串或数字
|
||||
:return: 如果合法返回True,否则返回False
|
||||
"""
|
||||
# 转换为字符串处理
|
||||
postcode_str = str(postcode)
|
||||
|
||||
# 中国邮政编码规则:
|
||||
# 1. 6位数字
|
||||
# 2. 第一位不能是0
|
||||
pattern = r'^[1-9]\d{5}$'
|
||||
|
||||
return bool(re.fullmatch(pattern, postcode_str))
|
||||
|
||||
|
||||
def encode_path_to_url(local_path: str) -> str:
|
||||
"""
|
||||
将本地文件路径转换为URL编码的相对路径
|
||||
|
||||
参数:
|
||||
local_path: 本地路径(如 "C:\\data\\报告.pdf" 或 "/var/www/文件.txt")
|
||||
|
||||
返回:
|
||||
URL编码的相对路径(如 "data/%E6%8A%A5%E5%91%8A.pdf")
|
||||
|
||||
处理逻辑:
|
||||
1. 统一路径分隔符为/
|
||||
2. 移除Windows盘符
|
||||
3. 分段编码每个路径部分
|
||||
4. 保留路径中的/分隔符
|
||||
"""
|
||||
# 统一路径分隔符为POSIX格式
|
||||
normalized_path = local_path.replace('\\', '/')
|
||||
|
||||
# 移除Windows盘符(如 C:/)
|
||||
normalized_path = re.sub(r'^[A-Za-z]:/', '', normalized_path)
|
||||
|
||||
# 移除开头多余的/
|
||||
normalized_path = normalized_path.lstrip('/')
|
||||
|
||||
# 分段处理每个路径部分
|
||||
encoded_parts = []
|
||||
for part in normalized_path.split('/'):
|
||||
if part:
|
||||
# 对每个路径段进行URL编码(保留. _ - 不编码)
|
||||
encoded_part = quote(part, safe='.-_')
|
||||
encoded_parts.append(encoded_part)
|
||||
|
||||
# 拼接编码后的路径
|
||||
return '/'.join(encoded_parts)
|
||||
|
||||
|
||||
def to_datetime(dt_str: str, fmt_list: List[str]):
|
||||
"""
|
||||
字符串转时间日期对象。
|
||||
|
||||
:param dt_str: 需要转日期格式的字符串
|
||||
:param fmt_list: 用于转换的日期格式列表,注意将最有可能的放在前面
|
||||
"""
|
||||
_date = None
|
||||
|
||||
for _fmt in fmt_list:
|
||||
if _date is None:
|
||||
try:
|
||||
_date = datetime.datetime.strptime(dt_str, _fmt)
|
||||
except (ValueError, Exception):
|
||||
pass
|
||||
else:
|
||||
return _date
|
||||
|
||||
return _date
|
||||
Reference in New Issue
Block a user