Unity3D C#游戏开发:个人码自动添加短横线问题求助
解决Unity中C#输入框每2位自动添加短横线的问题
首先,咱们来拆解你遇到的问题,再一步步给出可行的解决方案:
原正则表达式的问题分析
你用的Regex.Replace(codeText, "([A-Za-z0-9][^-]){2}", "$0-");存在几个关键漏洞:
- 匹配逻辑错误:
([A-Za-z0-9][^-]){2}是重复匹配「字母数字+非短横线」这个组合两次,意味着要凑够4个符合条件的字符才会触发替换——这就是为什么只有前两位看似生效(实际是输入前两位时的偶然匹配,逻辑完全不符合需求)。 - 未排除已有的分隔符:正则没有忽略已经添加的短横线,当输入中出现
-后,后续扫描可能会把-前后的字符凑成新的匹配组,导致重复添加短横线,甚至无限循环。 - 没有避免末尾加横线:即使逻辑正确,也会在最后一组字符后面多添一个
-,不符合你要的XX-XX-XX-XX-XX格式。
正确的实现方案
我们需要先清理输入、限制有效长度,再用正确的正则格式化,同时还要处理Unity InputField的光标位置和无限触发问题,具体代码如下:
using UnityEngine; using UnityEngine.UI; using System.Text.RegularExpressions; public class CodeInputManager : MonoBehaviour { public InputField personalCodeInput; private string lastFormattedText = ""; void Start() { // 绑定输入框的内容变化事件 personalCodeInput.onValueChanged.AddListener(FormatPersonalCode); } void FormatPersonalCode(string rawInput) { // 1. 清理输入:只保留字母和数字,去掉所有已有的短横线 string cleanedInput = Regex.Replace(rawInput, "[^A-Za-z0-9]", ""); // 2. 限制最多10个有效字符(5组×2位),避免用户输入过多 if (cleanedInput.Length > 10) { cleanedInput = cleanedInput.Substring(0, 10); } // 3. 每2位添加短横线,用负向预查(?!$)避免在最后一组后面加横线 string formattedCode = Regex.Replace(cleanedInput, "(.{2})(?!$)", "$1-"); // 4. 避免无限触发onValueChanged(因为我们修改了输入框文本) if (formattedCode != lastFormattedText) { lastFormattedText = formattedCode; // 保存并调整光标位置,提升输入体验 int originalCursorPos = personalCodeInput.caretPosition; personalCodeInput.text = formattedCode; // 计算调整后的光标位置:如果原位置在新增横线的区域,自动跳过横线 int adjustedPos = originalCursorPos + (formattedCode.Length - rawInput.Length); personalCodeInput.caretPosition = Mathf.Clamp(adjustedPos, 0, formattedCode.Length); } } }
代码关键点解释
- 输入清理:
Regex.Replace(rawInput, "[^A-Za-z0-9]", "")确保输入中只保留有效字符,彻底避免已有的短横线干扰格式化逻辑。 - 长度限制:直接截断到10个有效字符,保证最终格式刚好是5组2位字符。
- 正确的正则:
"(.{2})(?!$)"匹配每2个字符,(?!$)是负向预查,意思是「后面不是字符串结尾」,这样就只会在中间的分组之间添加短横线,不会在最后多添。 - 光标处理:修改输入框文本会触发
onValueChanged,所以用lastFormattedText做缓存避免循环;同时调整光标位置,让用户输入时不会因为格式化导致光标跳转到末尾,体验更自然。
额外提示
因为你提到已经单独验证了每组的字符/数字对,你可以在FormatPersonalCode方法里加上验证逻辑,比如检查每一组是否符合你的规则(比如前两组是数字,后三组是字母之类的),如果不符合可以给用户提示或者拒绝输入。
内容的提问来源于stack exchange,提问作者Martin Pfeifhofer
相关产品推荐
相关产品推荐

