随机名字
游戏中时常会有默认随机名字的需求,而在处理这种名字时,如何对名字的长度判断便成了一个问题
#####具体需求
- 服务器给一个随机的名 + 姓 + 轮次,要求客户端拼接成 名·姓1 这样的结构,其中名和姓中间跟一个”·“字符,姓后面跟着轮次序号
- 名字的长度为3-12个英文字符,若超出长度,则从右向左截取,其中轮次不截取,若刚好把姓截取完,则不显示中间字符,改为显示”名1“这样的结构。
- 例如安德森·罗德里12,这里一个中文算两个字符,"·"算两个,所以总共应该是16个字符,超出了限制,应该截取姓,显示为安德森·罗12。
#####遇到的问题
- 在lua中,一个中文是相当于三个英文字符,而在服务器的判断逻辑中,一个中文被认为是两个英文字符,所以首先要处理这方面的冲突
- 根据需求,思路为先判断长度,然后一个一个字节的从右向左截取,直到满足长度为止,其中需要对刚好把姓截取完的特殊处理
#####解决方法
- 处理问题一
这里使用了正则匹配UTF-8字符来匹配汉字和汉字字符来达成筛选汉字的目的
写一个函数用于获得名字长度
-- 获得名字长度
function CreateRoleSelectSkinUI.getNameLength(name)
local len = 0;
-- 正则匹配UTF-8字符
for uchar in string.gmatch(name, "[%z\1-\127\194-\244][\128-\191]*") do
-- 除中文都算一个长度
if string.find(uchar, "[%w%p%s]") then
len = len + 1;
else
len = len + 2;
end
end
return len;
end
- 处理问题二
根据传入参数截取名字前n个字符
-- 截取名字前len个字符
function CreateRoleSelectSkinUI.subNameByLength(str, len)
local i = 0;
local sub_str = "";
-- 正则匹配UTF-8字符
for uchar in string.gmatch(str, "[%z\1-\127\194-\244][\128-\191]*") do
if string.find(uchar, "[%w%p%s]") then
i = i + 1;
else
i = i + 2;
end
sub_str = sub_str .. uchar;
if i >= len then
break;
end
end
return sub_str;
end
#####最终处理函数
-- 设置随机名字(名+姓+轮次)
function CreateRoleSelectSkinUI.setRandomName(para)
local roundStr = iif(para.round <= 0, "", para.round);
local firstNameStr = LocalizationManager.GetTranslationText(para.first_name);
local lastNameStr = LocalizationManager.GetTranslationText(para.last_name);
local firstLen = this.getNameLength(firstNameStr);
local lastLen = this.getNameLength(lastNameStr);
local roundLen = this.getNameLength(roundStr);
local nameStr = firstNameStr .. "·" .. lastNameStr;
for i = this.getNameLength(nameStr), 1, -1 do
nameStr = this.subNameByLength(nameStr, i);
-- 若最右边是符号,则一起删除
if this.getNameLength(nameStr) == firstLen + 2 then
i = i - 2;
nameStr = firstNameStr;
end
-- 若满足条件,则加上轮次返回
if this.getNameLength(nameStr) <= 12 - roundLen then
nameStr = nameStr .. roundStr;
break;
end
end
this.btnInputName.text = nameStr;
end