Regex - 带有 .和 ,

Regex - Numeric regex with . and ,

我必须创建一个正则表达式,允许用户仅输入一个数字(使用 . 或 ,)

所以这些例子都是有效的:

这是我当前的代码

private regex: RegExp = new RegExp(/^\d*[\,\.]{0,1}\d{1,2}/g);

然而,这让我可以输入 8.,5,这显然很糟糕。如何更改我的正则表达式,以便用户只能放置 1 个十进制字符 , OR .?

编辑:

我试过很多答案,但大多数都不起作用(我不能放置任何小数字符)。基本上我在 angular 中创建一个指令,将 <input type="text"> 转换为数字输入(我不能使用 type="number"

这是我的指令代码(参见 Angular2 - Input Field To Accept Only Numbers

@Directive({
    selector: "[OnlyNumber]"
})
export class OnlyNumberDirective {
    // Allow decimal numbers. The \. is only allowed once to occur
    private regex: RegExp = new RegExp(/^(?=.+)\d*(?:[\,\.]\d{1,2})?$/g);
    // Allow key codes for special events. Reflect :
    // Backspace, tab, end, home
    private specialKeys: Array<string> = ["Backspace", "Tab", "End", "Home"];

    constructor(private el: ElementRef) {
    }

    @HostListener("keydown", ["$event"])
    onKeyDown(event: KeyboardEvent) {
        // Allow Backspace, tab, end, and home keys
        if (this.specialKeys.indexOf(event.key) !== -1) {
            return;
        }
        let current: string = this.el.nativeElement.value;
        let next: string = current.concat(event.key);
        if (next && !String(next).match(this.regex)) {
            event.preventDefault();
        }
    }
}

这是我在模板中使用它的方式:

<mat-form-field class="numeric-textbox">
    <input matInput
           OnlyNumber
           #model="ngModel"
           placeholder="{{ label }}"
           [ngModel]="selectedValue"/>
    <mat-error><ng-content></ng-content></mat-error>
</mat-form-field>

您应该使用 $ 指定输入字符串的结尾,否则将发生部分匹配。你不应该寻找 \d* 除非你想匹配 .5,5 之类的值,否则它们将匹配为有效输入。

^\d+(?:[.,]\d{1,2})?$

注意: 您不需要在字符 class 内转义点或逗号,而像 [.,]{0,1} 这样的量词实际上等于 [.,]?

现场演示:

document.getElementById("number").addEventListener("keyup",function(e) {
  console.log(this.value.match(/^\d+(?:[.,]\d{1,2})?$/));
});
<input type="text" id="number" placeholder="Enter a number">

更新,基于评论

^(?![.,]?$)\d*[,.]?(?:\d{1,2})?$

这允许任何数字后面或前面有一个小数点或逗号。

Live demo

正则表达式是正确的,买你只需要匹配整个字符串: ^ 字符串的开始 $ 字符串结尾

但是,可以通过以下方式改进正则表达式:

^   : for start of string
\d+ : for at least 1 digit
(
  [\,\.] : 1 comma
  \d{1,2} : followed by 1 digit or two
)?  : keep this optionnal. We can get numbers without commas
$  : end of string

最终的正则表达式可能是:

/^\d+([\,\.]\d{1,2})?$/

您的正则表达式非常好,您只需要指定行的终止。您目前正在匹配 8,.5 中的 8,这可能是您遇到正则表达式问题的原因。我假设您正在使用 JavaScript 的 test() 函数并获得 true 作为该字符串的响应。只需将 $ 附加到您的正则表达式,您就会得到正确的答案。您还可以将正则表达式简化为以下内容(也在下面的代码段中注释掉)。您也可以在尝试匹配字符串一次而不是多次时删除 g 标志:

^\d*[,.]?\d{1,2}$

你匹配的是什么:

var a = ['8.5', '8,5', '.5', ',5', '8.,5']
var r = /^\d*[\,\.]{0,1}\d{1,2}/g

a.forEach(function(s){
  console.log(s.match(r))
})

你应该匹配什么:

var a = ['8.5', '8,5', '.5', ',5', '8.,5']
var r = /^\d*[\,\.]{0,1}\d{1,2}$/g
// var r = /^\d*[,.]?\d{1,2}$/

a.forEach(function(s){
  console.log(s.match(r))
})

尝试:/^(?=.+)\d*(?:[,.]\d{1,2})?$/g

let regex = /^(?=.+)\d*(?:[,.]\d{1,2})?$/g,
strings = ["5", "50", "500", ".5", ",5","5.5","5,5", "5.55", "5,55", "5.555", "5,555", "5,,5", "5..5", "5,.5", "5.,5", "5,", "5."];

strings.forEach((string) => {
   console.log(`${regex} ${string.match(regex) ? `matches ${string.match(regex)}`: `has no match for ${string}`}`);
});

这将匹配:

从一开始,先行确保存在字符(一个或多个),然后开始匹配:任意数量的数字(0 个或多个),以及以下可选:逗号或点,然后是字符串末尾前的 1 或 2 位数字。