forked from moyin/whale-town-front
200 lines
5.4 KiB
GDScript
200 lines
5.4 KiB
GDScript
class_name StringUtils
|
||
|
||
# 字符串工具类 - 提供常用的字符串处理功能
|
||
|
||
# 验证邮箱格式
|
||
static func is_valid_email(email: String) -> bool:
|
||
var regex = RegEx.new()
|
||
regex.compile("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$")
|
||
return regex.search(email) != null
|
||
|
||
# 验证用户名格式(字母、数字、下划线)
|
||
static func is_valid_username(username: String) -> bool:
|
||
if username.is_empty() or username.length() > 50:
|
||
return false
|
||
|
||
var regex = RegEx.new()
|
||
regex.compile("^[a-zA-Z0-9_]+$")
|
||
return regex.search(username) != null
|
||
|
||
# 验证密码强度
|
||
static func validate_password_strength(password: String) -> Dictionary:
|
||
var result = {"valid": false, "message": "", "strength": 0}
|
||
|
||
if password.length() < 8:
|
||
result.message = "密码长度至少8位"
|
||
return result
|
||
|
||
if password.length() > 128:
|
||
result.message = "密码长度不能超过128位"
|
||
return result
|
||
|
||
var has_letter = false
|
||
var has_digit = false
|
||
var has_special = false
|
||
|
||
for i in range(password.length()):
|
||
var char = password[i]
|
||
if char >= 'a' and char <= 'z' or char >= 'A' and char <= 'Z':
|
||
has_letter = true
|
||
elif char >= '0' and char <= '9':
|
||
has_digit = true
|
||
elif char in "!@#$%^&*()_+-=[]{}|;:,.<>?":
|
||
has_special = true
|
||
|
||
var strength = 0
|
||
if has_letter:
|
||
strength += 1
|
||
if has_digit:
|
||
strength += 1
|
||
if has_special:
|
||
strength += 1
|
||
if password.length() >= 12:
|
||
strength += 1
|
||
|
||
result.strength = strength
|
||
|
||
if not (has_letter and has_digit):
|
||
result.message = "密码必须包含字母和数字"
|
||
return result
|
||
|
||
result.valid = true
|
||
result.message = "密码强度: " + ["弱", "中", "强", "很强"][min(strength - 1, 3)]
|
||
return result
|
||
|
||
# 截断字符串
|
||
static func truncate(text: String, max_length: int, suffix: String = "...") -> String:
|
||
if text.length() <= max_length:
|
||
return text
|
||
return text.substr(0, max_length - suffix.length()) + suffix
|
||
|
||
# 首字母大写
|
||
static func capitalize_first(text: String) -> String:
|
||
if text.is_empty():
|
||
return text
|
||
return text[0].to_upper() + text.substr(1)
|
||
|
||
# 转换为标题格式(每个单词首字母大写)
|
||
static func to_title_case(text: String) -> String:
|
||
var words = text.split(" ")
|
||
var result = []
|
||
for word in words:
|
||
if not word.is_empty():
|
||
result.append(capitalize_first(word.to_lower()))
|
||
return " ".join(result)
|
||
|
||
# 移除HTML标签
|
||
static func strip_html_tags(html: String) -> String:
|
||
var regex = RegEx.new()
|
||
regex.compile("<[^>]*>")
|
||
return regex.sub(html, "", true)
|
||
|
||
# 格式化文件大小
|
||
static func format_file_size(bytes: int) -> String:
|
||
var units = ["B", "KB", "MB", "GB", "TB"]
|
||
var size = float(bytes)
|
||
var unit_index = 0
|
||
|
||
while size >= 1024.0 and unit_index < units.size() - 1:
|
||
size /= 1024.0
|
||
unit_index += 1
|
||
|
||
if unit_index == 0:
|
||
return str(int(size)) + " " + units[unit_index]
|
||
else:
|
||
return "%.1f %s" % [size, units[unit_index]]
|
||
|
||
# 将UTC时间字符串转换为本地时间显示
|
||
static func format_utc_to_local_time(utc_time_str: String) -> String:
|
||
# 解析UTC时间字符串 (格式: 2025-12-25T11:23:52.175Z)
|
||
var regex = RegEx.new()
|
||
regex.compile("(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})")
|
||
var result = regex.search(utc_time_str)
|
||
|
||
if result == null:
|
||
return utc_time_str # 如果解析失败,返回原字符串
|
||
|
||
# 提取时间组件
|
||
var year = int(result.get_string(1))
|
||
var month = int(result.get_string(2))
|
||
var day = int(result.get_string(3))
|
||
var hour = int(result.get_string(4))
|
||
var minute = int(result.get_string(5))
|
||
var second = int(result.get_string(6))
|
||
|
||
# 创建UTC时间字典
|
||
var utc_dict = {
|
||
"year": year,
|
||
"month": month,
|
||
"day": day,
|
||
"hour": hour,
|
||
"minute": minute,
|
||
"second": second
|
||
}
|
||
|
||
# 转换为Unix时间戳(UTC)
|
||
var utc_timestamp = Time.get_unix_time_from_datetime_dict(utc_dict)
|
||
|
||
# 获取本地时间(Godot会自动处理时区转换)
|
||
var local_dict = Time.get_datetime_dict_from_unix_time(utc_timestamp)
|
||
|
||
# 格式化为易读的本地时间
|
||
return "%04d年%02d月%02d日 %02d:%02d:%02d" % [
|
||
local_dict.year,
|
||
local_dict.month,
|
||
local_dict.day,
|
||
local_dict.hour,
|
||
local_dict.minute,
|
||
local_dict.second
|
||
]
|
||
|
||
# 获取相对时间描述(多少分钟后)
|
||
static func get_relative_time_until(utc_time_str: String) -> String:
|
||
# 解析UTC时间字符串
|
||
var regex = RegEx.new()
|
||
regex.compile("(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})")
|
||
var result = regex.search(utc_time_str)
|
||
|
||
if result == null:
|
||
return "时间格式错误"
|
||
|
||
# 提取时间组件
|
||
var year = int(result.get_string(1))
|
||
var month = int(result.get_string(2))
|
||
var day = int(result.get_string(3))
|
||
var hour = int(result.get_string(4))
|
||
var minute = int(result.get_string(5))
|
||
var second = int(result.get_string(6))
|
||
|
||
# 创建UTC时间字典
|
||
var utc_dict = {
|
||
"year": year,
|
||
"month": month,
|
||
"day": day,
|
||
"hour": hour,
|
||
"minute": minute,
|
||
"second": second
|
||
}
|
||
|
||
# 转换为Unix时间戳
|
||
var target_timestamp = Time.get_unix_time_from_datetime_dict(utc_dict)
|
||
var current_timestamp = Time.get_unix_time_from_system()
|
||
|
||
# 计算时间差(秒)
|
||
var diff_seconds = target_timestamp - current_timestamp
|
||
|
||
if diff_seconds <= 0:
|
||
return "现在可以重试"
|
||
elif diff_seconds < 60:
|
||
return "%d秒后" % diff_seconds
|
||
elif diff_seconds < 3600:
|
||
var minutes = int(diff_seconds / 60)
|
||
return "%d分钟后" % minutes
|
||
else:
|
||
var hours = int(diff_seconds / 3600)
|
||
var minutes = int((diff_seconds % 3600) / 60)
|
||
if minutes > 0:
|
||
return "%d小时%d分钟后" % [hours, minutes]
|
||
else:
|
||
return "%d小时后" % hours
|