You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular使用正则exec验证器限制MatInput输入并保持可编辑的实现方法

结论

不可以直接将该验证器作为动态maxlength属性实现需求,原因是maxlength仅限制输入的总字符数,无法适配「小数点前最多6位、小数点后最多2位」的分段校验规则,举个反例:如果把总长度设为8(6位整数+小数点+2位小数的最大长度),用户输入纯整数1234567时,总长度仅7位未触发maxlength限制,但已经违反了整数位最多6位的规则。

前置修正:你的验证器逻辑写反了

Angular 自定义验证器的规则是:校验通过返回null,校验不通过返回错误对象,你当前的代码刚好写反了,会导致符合规则的内容被判定为校验失败,先修正:

public static floatingAmount(c: FormControl) {
    const reg = /^[0-9]{1,6}([,.][0-9]{1,2})?$/;
    const isValid = reg.test(c.value);
    return isValid ? null : { floatingAmount: true };
}

正确实现方案

要实现「不符合规则的内容禁止输入」的效果,推荐监听输入框的input事件做实时内容过滤,配合验证器做兜底校验即可:

模板代码

<mat-form-field>
  <input matInput 
         [formControl]="amountControl"
         (input)="handleAmountInput($event)"
         placeholder="输入金额">
  <!-- 校验错误提示 -->
  <mat-error *ngIf="amountControl.hasError('floatingAmount')">
    最多支持6位整数、2位小数
  </mat-error>
</mat-form-field>

组件逻辑代码

// 输入事件处理,实时过滤非法内容
handleAmountInput(event: Event): void {
  const inputEl = event.target as HTMLInputElement;
  let inputVal = inputEl.value;
  // 第一步:过滤掉所有非数字、小数点、逗号的字符
  inputVal = inputVal.replace(/[^0-9,.]/g, '');

  const separatorIndex = Math.max(inputVal.indexOf('.'), inputVal.indexOf(','));
  if (separatorIndex > -1) {
    // 存在小数点/逗号:限制整数位最多6位,小数位最多2位
    const intPart = inputVal.slice(0, separatorIndex).slice(0, 6);
    const decimalPart = inputVal.slice(separatorIndex + 1).slice(0, 2);
    inputVal = `${intPart}.${decimalPart}`;
  } else {
    // 无小数点:最多6位整数
    inputVal = inputVal.slice(0, 6);
  }

  // 把处理后的值回写到输入框和表单控件
  inputEl.value = inputVal;
  this.amountControl.setValue(inputVal, { emitEvent: false });
}

这个方案可以完全符合你的需求,输入过程中就会自动拦截不符合规则的内容,不会允许用户输入超出限制的数字。

内容的提问来源于stack exchange,提问作者Jonny

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 18:06:02