检查字符串是否仅包含数字的正则表达式

439
hash = window.location.hash.substr(1);
var reg = new RegExp('^[0-9]$');
console.log(reg.test(hash));
我在"123""123f"都得到了false。我想检查哈希值是否只包含数字。我有什么遗漏吗?

3
根据W3schools的说明,只有在方括号内部时,“^”才能否定字符序列,因此“[^0-9]”表示非数字,但“^[0-9]”则表示“行开头”。 - user1299656
21个回答

714
var reg = /^\d+$/;

应该这样做。原始匹配项适用于仅由一个数字组成的内容。


10
@vsync,因为单引号字符串中的\d被解释成字母'd'。请在JavaScript控制台中运行'/^\d+$/' === '/^d+$/'。在字符串中嵌入正则表达式时,需要进行双重转义:eval('/^\\d+$/') - Mike Samuel
5
不考虑负数。 - Giuseppe Pes
14
@GiuseppePes。正确。它也无法处理实数、复数、四元数等。问题涉及计数数字,我的回答也是如此。 - Mike Samuel
10
这是一个正则表达式,用于匹配数字,包括可选的正负号、整数部分、小数点、小数部分和指数符号。 - Richeve Bebedor
1
@D_N。好的。回到你最初的观点,是的,在许多编程语言中,008是一个错误标记,因为它看起来像一个八进制字面量,但在标准数学表示法中,基数₁₀是隐含的。我不知道提问者想要什么,如果我要拒绝格式错误的八进制,我应该匹配有效的十六进制,并决定是否包括Python3/Java数字,如123_456或C++ 123'456。在没有更多上下文(如特定的编程或人类语言)的情况下,\d+似乎是一个折衷方案,并且作者的第一次尝试强烈建议使用它。 - Mike Samuel
显示剩余12条评论

170

正如您所说,您希望哈希表只包含数字。

const reg = new RegExp('^[0-9]+$');
或者
const reg = new RegExp('^\d+$')

\d[0-9] 意义相同。 使用 + 表示搜索一个或多个出现的 [0-9]。


9
这并不完全正确,[0-9] 和 \d 不是同一个意思,\d 还可以匹配来自其他字符集,如希伯来语和中文的数字字符。 - Michiel

89

这个可以允许有正负数和小数点,也可以是空字符串:

var reg = /^-?\d*\.?\d*$/

如果您不想允许空字符串,请使用此代码:

var reg = /^-?\d+\.?\d*$/

你的第二个正则表达式非常有帮助。它只是在验证像.378这样的数字时卡住了。您能否友好地告诉我如何调整 /^-?\d+.?\d*$/ 以便它也可以验证 .378? - hellojava
1
+替换为*^-?\d*\.?\d*$+表示至少在前面找一个数字,*表示找零个或多个数字。 - Setthase
3
为了更好地使用浮点数,请使用 /^-?\d+(.\d+)?$/。 - blazkovicz
5
如果您不想允许空值但是想要允许像.25这样的语法,可以使用 var reg = /^-?\d*[\.]?\d+$/ - Matt McClellan
1
这个线程非常有帮助!这是一个正则表达式,它处理加减号以及E符号。 ^[-+]?\d.?\d(\d+[eE][-+]?)?\d+$ - Hoonerbean
显示剩余3条评论

72
var validation = {
    isEmailAddress:function(str) {
        var pattern =/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
        return pattern.test(str);  // returns a boolean
    },
    isNotEmpty:function (str) {
        var pattern =/\S+/;
        return pattern.test(str);  // returns a boolean
    },
    isNumber:function(str) {
        var pattern = /^\d+\.?\d*$/;
        return pattern.test(str);  // returns a boolean
    },
    isSame:function(str1,str2){
        return str1 === str2;
    }
};   

alert(validation.isNotEmpty("dff"));
alert(validation.isNumber(44));
alert(validation.isEmailAddress("mf@tl.ff"));
alert(validation.isSame("sf","sf"));

不支持浮点数 - Weijing Jay Lin
1
@WeijingJayLin 不用担心,这个库的新版本会修复这个 bug。 - winwin
我认为isNumber模式应该是 => /^\d*.?\d+$/,这样它将接受.9但不会接受9。 - Mohamed Kamel

34
^[0-9]$ 

...是一个正则表达式,匹配任何单个数字,因此1将返回true,但123将返回false。

如果您添加*量词,

^[0-9]*$

表达式将匹配任意长度的数字字符串,123将返回true。(123f仍将返回false)。

请注意,从技术上讲,空字符串是一个长度为0的数字字符串,因此使用^[0-9]*$ 它将返回true。如果您只想接受包含1个或多个数字的字符串,请使用+而不是*。

^[0-9]+$

正如其他许多人指出的那样,有很多种方法可以实现这一点,但我觉得值得指出的是,原始问题中的代码只需要一个额外的字符就可以按预期工作。


27
这对于您的需求来说已经过度了:
const numberReSnippet = "NaN|-?((\d*\.\d+|\d+)([Ee][+-]?\d+)?|Infinity)";
const matchOnlyNumberRe = new RegExp("^("+ numberReSnippet + ")$");

据我所知,这与Java和JavaScript可能会抛出的所有数字变化相匹配,包括“-Infinity”,“1e-24”和“NaN”。它还可以匹配您可能键入的数字,例如“-.5”。
就其撰写而言,“numberReSnippet”旨在放入其他正则表达式中,因此您可以提取(或避免)数字。尽管有许多括号,但它不包含任何捕获组。因此,“matchOnlyNumberRe”仅匹配字符串是数字,并对整个字符串进行了捕获。
以下是Jasmine测试,以便您了解它处理和不处理哪些内容:
describe("Number Regex", function() {
    const re = matchOnlyNumberRe;
    it("Matches Java and JavaScript numbers", function() {
        expect(re.test(         "1")).toBe(true);
        expect(re.test(       "0.2")).toBe(true);
        expect(re.test(     "0.4E4")).toBe(true);  // Java-style
        expect(re.test(       "-55")).toBe(true);
        expect(re.test(      "-0.6")).toBe(true);
        expect(re.test(  "-0.77E77")).toBe(true);
        expect(re.test(      "88E8")).toBe(true);
        expect(re.test(       "NaN")).toBe(true);
        expect(re.test(  "Infinity")).toBe(true);
        expect(re.test( "-Infinity")).toBe(true);
        expect(re.test(     "1e+24")).toBe(true);  // JavaScript-style
    });
    it("Matches fractions with a leading decimal point", function() {
        expect(re.test(        ".3")).toBe(true);
        expect(re.test(       "-.3")).toBe(true);
        expect(re.test(     ".3e-4")).toBe(true);
    });
    it("Doesn't match non-numbers", function() {
        expect(re.test(         ".")).toBe(false);
        expect(re.test(        "9.")).toBe(false);
        expect(re.test(          "")).toBe(false);
        expect(re.test(         "E")).toBe(false);
        expect(re.test(       "e24")).toBe(false);
        expect(re.test(   "1e+24.5")).toBe(false);
        expect(re.test("-.Infinity")).toBe(false);
        expect(re.test(      "8|24")).toBe(false);
    });
});

IsNumber仅检查是否为整数,但根据其名称,它应该检查是否为数字(双精度、整数)。我认为这个答案比其他答案更全面。 - Dabbas
2
部分 [E|e][+|-]? 是不正确的。看起来你在想 (?:E|e)(?:\+|-)?,并且在将其转换为字符集时忘记了删除 |。当您使用分组指定替代方案时,需要 |,但在字符集中,所列出的选择项自动成为彼此的替代方案,而 | 没有特殊含义。因此,类似 [E|e] 的内容允许 Ee 和字符 | - Louis
因此,正确的正则表达式(不包括非捕获组和双斜杠)是:/NaN|-?((\d*\.\d+|\d+)([Ee][+-]?\d+)?|Infinity)/。 我更改了浮点数和整数的顺序,以使表达式更加贪婪。 - Simon Zyx
谢谢,我已经将正则表达式更改为@SimonZyx的,并添加了一个单元测试来确认原始代码存在错误。 - David Leppik

18

\d将无法匹配小数点。使用以下内容来匹配小数。

const re = /^\d*(\.\d+)?$/
'123'.match(re)       // true
'123.3'.match(re)     // true
'123!3'.match(re)     // false

虽然这是一个好的正则表达式,但它也会匹配只包含点的字符串(例如:'.....'.match(re) //true)。 - Mihai Cicu
2
不是所有的事情都应该交给正则表达式处理 :) 存在着前提条件的前提条件,未知的未知数。 - Muhammad Adeel
1
先生说得好 :) 作为跟进,我们可以使用“/^\d*(.\d+)?$/”更好地匹配正浮点数。 - Mihai Cicu

11

这个函数检查它的输入是否符合经典意义上的数字,就像人们期望正常数字检测函数应该工作一样。

例如,它可以用于HTML表单输入的测试。

它绕过了所有JS的传说,比如tipeof(NaN) = number,parseint('1 Kg') = 1,布尔值被强制转换为数字等。

它通过将参数呈现为字符串,并将该字符串与类似于@codename-的正则表达式进行比较,但允许像5.和.5这样的条目。

function isANumber( n ) {
    var numStr = /^-?(\d+\.?\d*)$|(\d*\.?\d+)$/;
    return numStr.test( n.toString() );
}

not numeric:
Logger.log( 'isANumber( "aaa" ): ' + isANumber( 'aaa' ) );
Logger.log( 'isANumber( "" ): ' + isANumber( '' ) );
Logger.log( 'isANumber( "lkjh" ): ' + isANumber( 'lkjh' ) );
Logger.log( 'isANumber( 0/0 ): ' + isANumber( 0 / 0 ) );
Logger.log( 'isANumber( 1/0 ): ' + isANumber( 1 / 0 ) );
Logger.log( 'isANumber( "1Kg" ): ' + isANumber( '1Kg' ) );
Logger.log( 'isANumber( "1 Kg" ): ' + isANumber( '1 Kg' ) );
Logger.log( 'isANumber( false ): ' + isANumber( false ) );
Logger.log( 'isANumber( true ): ' + isANumber( true ) );

numeric:
Logger.log( 'isANumber( "0" ): ' + isANumber( '0' ) );
Logger.log( 'isANumber( "12.5" ): ' + isANumber( '12.5' ) );
Logger.log( 'isANumber( ".5" ): ' + isANumber( '.5' ) );
Logger.log( 'isANumber( "5." ): ' + isANumber( '5.' ) );
Logger.log( 'isANumber( "-5" ): ' + isANumber( '-5' ) );
Logger.log( 'isANumber( "-5." ): ' + isANumber( '-5.' ) );
Logger.log( 'isANumber( "-.5" ): ' + isANumber( '-5.' ) );
Logger.log( 'isANumber( "1234567890" ): ' + isANumber( '1234567890' ));

正则表达式的解释:

/^-?(\d+\.?\d*)$|(\d*\.?\d+)$/  

初始符号“^”和结束符号“$”匹配字符串的开头和结尾,以确保检查跨越整个字符串。 “-?”部分是带有“?”乘数的减号,允许其出现零次或一次。
然后有两个类似的由括号分隔的组。字符串必须匹配这两个组中的任意一个。第一个匹配像5.这样的数字,而第二个匹配.5
第一个组为:
\d+\.?\d*

"\d+" 匹配一个数字 (\d) 一次或多次。
"\.?" 是小数点(用“\”转义以避免其被视为特殊字符),出现零次或一次。
最后一个部分 "\d*" 再次是数字,出现零次或多次。
所有部分都是可选的,但第一个数字不可省略,因此该组匹配像 5. 这样的数字,而不是 .5,因为它们由另一半匹配。

4.5.3符合您的正则表达式。 - Virendra Singh Rathore
1
/^[+-]?\d*.?\d+(?:[Ee][+-]?\d+)?$/ - Richeve Bebedor
@RicheveBebedor 很好,你的版本增加了指数功能,这对于需要工程或天文学输入的情况非常好。我有意省略了它,寻求一个可以返回最小有效货币输入值集合的正则表达式。 - Juan Lanus

8
为什么不使用类似以下的内容:
$.isNumeric($(input).val())

jQuery被测试过,最常见的情况是被检查


1
你问为什么不只用jQuery。这里是为什么不用的原因:1. 如果你的代码还没有使用jQuery,只为检查值是否为数字而添加jQuery?我觉得不需要。2. 假设你已经有一个框架来运行一个正则表达式列表进行标记化。如果你不使用数字的正则表达式,你必须为它编写一个特殊情况:遍历正则表达式列表,然后还要使用jQuery检查令牌是否为数字。使代码复杂化。3. 如果您需要允许NaN或无限大,$.isNumeric将不起作用。 - Louis
1
现在是2018年。任何回答中如果没有明确要求使用jQuery作为解决方案,就应该被忽略。 - mwilson

8

如果您只需要正整数并且不需要前导零(例如“0001234”或“00”):

var reg = /^(?:[1-9]\d*|\d)$/;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接