需求
- 小數:
23.3、0.5、.8 (可選前導零)
- 分數:
33/12、1/2
- 禁止其他字符
正則表達式
// 完整匹配
/^(\d+\.\d*|\.\d+|\d+\/\d+)$/
// 解釋
^ # 開頭
( # 分組
\d+\.\d* | # 數字.數字 (23.3, 23.)
\.\d+ | # .數字 (.8)
\d+\/\d+ # 數字/數字 (33/12)
)
$ # 結尾
實時輸入過濾 (oninput)
<input id="numInput" oninput="filterInput(this)">
<script>
function filterInput(el) {
const val = el.value;
// 刪除非法字符:只保留 數字 . /
const cleaned = val.replace(/[^\d./]/g, '');
// 進一步限制:最多一個 . 或 /,且不同時存在
if ((cleaned.match(/\./g) || []).length > 1 ||
(cleaned.match(/\//g) || []).length > 1 ||
(cleaned.includes('.') && cleaned.includes('/'))) {
// 回退到上一個合法值 (需保存 oldValue)
el.value = el.dataset.lastValid || '';
return;
}
el.value = cleaned;
el.dataset.lastValid = cleaned;
}
</script>
表單提交驗證
function validate() {
const v = document.getElementById('numInput').value;
if (!/^(\d+\.\d*|\.\d+|\d+\/\d+)$/.test(v)) {
alert('請輸入小數(如23.3)或分數(如33/12)');
return false;
}
return true;
}
React 受控組件
const [val, setVal] = useState('');
const onChange = (e) => {
const v = e.target.value;
if (/^(\d*\.?\d*|\d*\/?\d*)$/.test(v)) { // 輸入中寬鬆匹配
setVal(v);
}
};