JavaScript正则:如何通过oninput模式匹配仅保留两位小数的浮点数
嘿,这个需求我熟!刚好之前做过类似的输入框实时过滤,给你一套完整的解决方案,既能满足「仅允许正负浮点数(可选两位小数)」的要求,还能兼顾用户输入体验👇
解决方案:实时过滤输入为合法正负浮点数
1. 核心正则与过滤逻辑
首先我们需要一个精准的正则来定位所有非法内容,再配合边界处理,确保输入始终符合要求。
非法字符匹配正则
这个正则会直接识别并移除所有不符合规则的内容:
const invalidCharsPattern = /[^-0-9.]|(?<=.)-|(?<=\..*)\.|(?<=\d{2})\d/g
给你拆解下每个部分的作用:
[^-0-9.]:匹配除负号、数字、小数点之外的所有无关字符(?<=.)-:干掉不在开头的负号(比如12-3里的-)(?<=\..*)\.:禁止多个小数点(比如12.34.5里的第二个.)(?<=\d{2})\d:限制小数点后最多两位(比如12.345里的最后一个5)
边界异常处理
光过滤还不够,还要处理用户可能输入的非常规开头:
- 多个负号(
--12→-12) - 直接输入小数点(
.34→0.34) - 负号后直接跟小数点(
-.34→-0.34)
2. 完整的Input事件处理器代码
重点提醒:直接修改input.value会导致光标跳到末尾,非常影响输入体验,所以我们要在处理后手动恢复光标位置!
const numberInput = document.querySelector('input[type="text"]'); numberInput.addEventListener('input', function(e) { const input = e.target; const cursorPos = input.selectionStart; const originalVal = input.value; // 第一步:过滤非法字符 let filteredVal = originalVal.replace(invalidCharsPattern, ''); // 第二步:处理边界异常情况 // 去掉开头多余的负号 if (filteredVal.startsWith('--')) { filteredVal = filteredVal.replace(/^--+/, '-'); } // 小数点开头自动补0 if (filteredVal.startsWith('.')) { filteredVal = '0' + filteredVal; } // 负号+小数点开头补0 if (filteredVal.startsWith('-.') && filteredVal.length === 2) { filteredVal = '-0' + filteredVal.slice(1); } // 第三步:仅当内容变化时更新,避免无限触发input事件 if (filteredVal !== input.value) { input.value = filteredVal; // 计算光标偏移量,恢复光标位置 const charDiff = originalVal.length - filteredVal.length; input.setSelectionRange(cursorPos - charDiff, cursorPos - charDiff); } });
3. 可选的额外优化
如果需要更严格的输入规则,可以加上这些补充:
- 禁止前导多0:比如把
0012.34改成12.34,把这段代码加到边界处理环节:// 移除前导多余的0(单个0保留) if (/^-?0\d/.test(filteredVal)) { filteredVal = filteredVal.replace(/^(-?)0+(?=\d)/, '$1'); } - 失焦时补全校验:如果用户输入了
-、.这种不完整内容,失焦时自动清空:numberInput.addEventListener('blur', function(e) { const val = e.target.value; if (['-', '.', '-.'].includes(val)) { e.target.value = ''; } });
这样用户在输入时,每一次按键都会实时过滤成合法格式,光标也不会乱跑,体验拉满~
内容的提问来源于stack exchange,提问作者molexus
相关产品推荐
相关产品推荐

