【问题标题】:Directive to limit decimal numbers to 100.00 max in text input (Regex)将文本输入中的十进制数限制为最大 100.00 的指令(正则表达式)
【发布时间】:2019-09-11 06:16:26
【问题描述】:

我有一个指令,即限制文本输入在文本输入中只写入十进制数

这是指令代码

 import { HostListener, Directive, ElementRef } from '@angular/core';

@Directive({
    exportAs: 'decimal-number-directive',
    selector: 'decimal-number-directive, [decimal-number-directive]',
})
export class DecimalNumberDirective {
    private regex: RegExp = new RegExp(/^\d*\.?\d{0,2}$/g);
    private specialKeys: string[] = ['Backspace', 'Tab', 'End', 'Home'];
    constructor(private el: ElementRef) {}
    @HostListener('keydown', ['$event'])
    onKeyDown(event: KeyboardEvent): void {
        if (this.specialKeys.indexOf(event.key) !== -1) {
            return;
        }

        const current: string = this.el.nativeElement.value;
        const next: string = current.concat(event.key);
        if (next && !String(next).match(this.regex)) {
            event.preventDefault();
        }
    }
}

这是我使用它的输入

<div class="col-2 pr-0">
                        <label>{{ l('Percent') }}</label>
                        <input
                            class="form-control"
                            type="text"
                            decimal-number-directive
                            name="percent"
                            [(ngModel)]="inquiryItemToAdd.percent"
                            maxlength="64"
                            (ngModelChange)="setTotalPrice()"
                            [readOnly]="!inquiryItemToAdd.servicePriceId || !servicePrice.isPriceCalculated"
                        />
                    </div>

但我可以写例如 155.00 或 155.56。我需要用 100.00 来限制它,因为我用它来写百分比。

我尝试使用这个正则表达式private regex: RegExp = new RegExp(/^(\d{1,2}(\.\d{1,2})?)|(100(\.0{1,2})?)$/g);,但我仍然可以使用 150%。

我该如何解决这个问题?

【问题讨论】:

  • 你有必要使用正则表达式吗?
  • 是的,有必要@AbuTaha

标签: javascript regex angular typescript


【解决方案1】:

它应该匹配从 0、0.0、0.00 到 100、100.0、100.00 的所有正数

正则表达式

^(\d{1,2}|\d{1,2}\.\d{1,2}|100\.[0]{1,2}|100)$

https://regex101.com/r/S9fbY7/3


更新

您需要允许 .要键入,因为 50. 不是有效模式,但 50.8 是,但每次击键都会验证整个正则表达式,因此您需要在按下 . 时更新您的代码绕过验证什么都不做,然后如果值以点可能会删除值或删除点或在点后添加 00

忽略的键:

private specialKeys: string[] = ['Backspace', 'Tab', 'End', 'Home', '.'];

在 Blur 上,您想要验证以 . 结尾的值。请注意根据您的用例选择任一选项。

if (val.endsWith('.')) {
  // Option 1 strip the . (dot)
  this.el.nativeElement.value = val.substring(0, val.length - 1); 

  // Option 2 add 00 after the . (dot)
  this.el.nativeElement.value = val + '00'; 

  // Option 3 remove the value all together
  this.el.nativeElement.value = ''; 
}

最终代码

import { HostListener, Directive, ElementRef } from '@angular/core';

@Directive({
  exportAs: 'decimal-number-directive',
  selector: 'decimal-number-directive, [decimal-number-directive]',
})
export class DecimalNumberDirective {
  private regex: RegExp = new RegExp(/^(\d{1,2}|\d{1,2}\.\d{1,2}|100\.[0]{1,2}|100)$/g);
  private specialKeys: string[] = ['Backspace', 'Tab', 'End', 'Home', '.'];
  constructor(private el: ElementRef) { }
  @HostListener('keydown', ['$event'])
  onKeyDown(event: KeyboardEvent): void {
    if (this.specialKeys.indexOf(event.key) !== -1) {
      return;
    }

    const current: string = this.el.nativeElement.value;
    const next: string = current.concat(event.key);
    if (next && !String(next).match(this.regex)) {
      event.preventDefault();
    }
  }

  @HostListener('blur', [])
  onBlur(): void {
    const val = this.el.nativeElement.value;
    if (val.endsWith('.')) {
      this.el.nativeElement.value = val.substring(0, val.length - 1); // Option 1 strip the .
      // this.el.nativeElement.value = val + '00'; // Option 2 add 00 after the .
      // this.el.nativeElement.value = ''; // Option 3 remove the value all together
    }
  }
}

【讨论】:

  • 不允许我输入.
  • 我不能输入 100
  • 这是现在的样子private regex: RegExp = new RegExp(/^(\d{1,2}|\d{1,2}\.\d{1,2}|100\.[0]{1,2}|100)$/g);
  • 您需要允许 .要键入,因为 50. 不是有效模式,但 50.8 是有效模式,但每次击键都会测量整个正则表达式,因此您需要在 .如果值以点结尾,则按下不执行任何操作并模糊可能会删除值或删除点
  • 我该怎么做?
【解决方案2】:

试试下面的正则表达式。

^ :- 它将始终检查以 100 开头的字符串
[0]{2} :- 它将检查. 之后必须只有 2 个零。

private regex: RegExp = /^100\.[0]{2}/gm;

您可以在此查看result

【讨论】:

  • 您必须转义点以匹配它,否则100X00 也会匹配。您可以省略字符类而只使用 0。请注意,这只会匹配以 100.00 开头的字符串。
  • 我不能用这个正则表达式输入任何东西
【解决方案3】:

我猜这个模式会起作用: ^(\d{0,2}(.\d{1,2})?|100(.00?)?)$

【讨论】:

  • 我可以输入 92309 但不能输入小数 这是它的样子 private regex: RegExp = new RegExp(/^(\d{0,2}(.\d{1,2})?|100(.00?)?)$/g);
  • 请试试这个:^(\d{0,2}(\.\d+)?|100(\.0+)?)$
  • 现在我无法输入 . 这是它的样子 private regex: RegExp = new RegExp(/^(\d{0,2}(\.\d+)?|100(\.0+)?)$/g);
  • 我已经测试过了,它可以工作,^(100(?:\.00?)?|\d?\d(?:\.\d\d?)?)$
猜你喜欢
  • 1970-01-01
  • 2018-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多