436
hash = window.location.hash.substr(1);
var reg = new RegExp('^[0-9]$');
console.log(reg.test(hash));

I get false on both "123" and "123f". I would like to check if the hash only contains numbers. Did I miss something?

Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75
Johan
  • 35,120
  • 54
  • 178
  • 293
  • 3
    According to W3schools ^ only negates sequences when *inside* the bracket, so [^0-9] refers to non-digits, but ^[0-9] does indicate "line beginning" – user1299656 May 11 '16 at 20:43

21 Answers21

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

should do it. The original matches anything that consists of exactly one digit.

Mike Samuel
  • 118,113
  • 30
  • 216
  • 245
  • 10
    @vsync, because `\d` in a single quoted string is the letter 'd'. Try running `'/^\d+$/' === '/^d+$/'` in your JavaScript console. You need to double-escape when embedding a RegExp in a string: `eval('/^\\d+$/')` – Mike Samuel Oct 18 '13 at 04:49
  • @vsync Why do you even want to do it? – Lucky Soni Jul 21 '14 at 06:06
  • 5
    It doesn't take into account negative number. – Giuseppe Pes May 27 '15 at 11:22
  • 14
    @GiuseppePes. True. It also doesn't handle real numbers, complex numbers, quaternions, etc. The question related to counting numbers and so does my answer. – Mike Samuel May 27 '15 at 16:59
  • I wouldn't call something like "007" a number but it will pass that expression. – Andrej Aug 02 '16 at 10:37
  • Yeah. 007 is octal 7 according to many languages' grammars (not strict mode JS) while 008 is not. The OP is ambiguous though, so unless you have a specific number grammar in mind I can't recommend ways to parse it. – Mike Samuel Aug 02 '16 at 22:17
  • 9
    `/^[\+\-]?\d*\.?\d+(?:[Ee][\+\-]?\d+)?$/` – Richeve Bebedor Feb 04 '17 at 23:19
  • what is the function of '\' in \+\- – user1169587 Sep 01 '17 at 02:32
  • @user1169587, It's not strictly necessary. `+` is a meta-character in regular expressions even though it doesn't have a special meaning inside a `[...]`. I try to be consistent to make things more readable/maintainable. For example, if I consistently escape all meta-characters, then I less likely to make a mistake if I later refactor `[\+\-]` into `(?:\+|\-)` as part of a larger edit. – Mike Samuel Sep 22 '17 at 16:11
  • Does it prevent + - and dot while typing on type number? – Arj 1411 Oct 05 '18 at 04:50
  • @AnandRaj, this pattern just specifies what will match. Nothing about this controls what happens when a user types. For that you might need to look into [``](https://www.the-art-of-web.com/html/html5-form-validation/) but you'll still need to check the format on the server. – Mike Samuel Oct 05 '18 at 13:23
  • The question says "string contains only numbers". 008 is not *a* number, but it is a string of numbers. –  Feb 21 '19 at 09:05
  • @D_N, if you want to debate which strings are numbers or the difference between numerals and numbers, I suggest you take it up with the person who posed the question. They get to define terms used in their questions. – Mike Samuel Feb 21 '19 at 19:55
  • @MikeSamuel it wasn't a complaint –  Feb 22 '19 at 00:03
  • 1
    @D_N. Fair enough. To your original point, yes `008` is an error token in many PLs because it starts like an octal literal, but in standard mathematical notation base ₁₀ is implied. I don't know which the asker wanted and if I were to reject malformed octal, I should match valid hex and decide whether to include Python3/Java numbers like `123_456` or C++ `123'456`. `\d+` seems like a middle ground in the absence of more context like a specific programming or human language and was strongly suggested by the author's first attempt. – Mike Samuel Feb 22 '19 at 15:36
  • @MikeSamuel Probably my looser grasp on terminology is making me opaque. What I meant to say was, yes, this solution seems to do what the asker wants, and the objections were treating it as if a string from a URL would be a non-base-10 number, but it's pretty obvious that's not the case from the context. I.e., desired to evaluate that each character is a numeral and not something else. This is a usual use case and helpful solution. Sorry for the confusion. –  Feb 22 '19 at 17:53
  • There is a problem with that variant. It passes array with single integer. [XXX], where x - number – John Smith Feb 17 '23 at 20:05
168

As you said, you want hash to contain only numbers.

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

or

const reg = new RegExp('^\d+$')

\d and [0-9] both mean the same thing. The + used means that search for one or more occurring of [0-9].

Nic
  • 597
  • 1
  • 4
  • 17
shadyabhi
  • 16,675
  • 26
  • 80
  • 131
  • 8
    This is not entirely true, [0-9] and \d are NOT the same, \d also matches numeric characters from other character sets such as hebrew and chinese. – Michiel Dec 08 '21 at 12:06
88

This one will allow also for signed and float numbers or empty string:

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

If you don't want allow to empty string use this one:

var reg = /^-?\d+\.?\d*$/
Setthase
  • 13,988
  • 2
  • 27
  • 30
  • Your second regex was really helpful. It just got stuck at validating a number like .378 Could you kindly let me know how to tweak /^-?\d+\.?\d*$/ so that it validates .378 as well – hellojava Aug 24 '13 at 14:39
  • 1
    Change `+` into `*`: `^-?\d*\.?\d*$`. `+` mean that you looking for at least one number on front, `*` looking for zero or many numbers. – Setthase Aug 26 '13 at 01:11
  • 3
    for float better use /^-?\d+(\.\d+)?$/ – blazkovicz Jan 23 '14 at 05:39
  • 5
    If you don't want to allow empty but want to allow syntax like .25 use `var reg = /^-?\d*[\.]?\d+$/` – Matt McClellan Apr 23 '14 at 19:04
  • If you want to test if a string is a parse-able number, including negatives and decimal: `/^-?\d+\.?\d*$|^\d*\.?\d+$/` – SpYk3HH Apr 05 '16 at 18:59
  • 1
    This thread was extremely helpful! Here's a regular expression I came up with that handles plus and minus signs, as well as E notation. ^[-+]?\d*\.?\d*(\d+[eE][-+]?)?\d+$ – Hoonerbean Oct 04 '17 at 20:21
  • related- the accepted answer here covers floating point very neatly (though not E notation!) https://stackoverflow.com/questions/12643009/regular-expression-for-floating-point-numbers – barlop Oct 16 '17 at 05:28
  • The second regex works perfect except its allowing Cntrl+C and Cntrl+V – Dextere Apr 26 '18 at 16:25
71
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"));
Dastagir
  • 982
  • 8
  • 14
34
^[0-9]$ 

...is a regular expression matching any single digit, so 1 will return true but 123 will return false.

If you add the * quantifier,

^[0-9]*$

the expression will match arbitrary length strings of digits and 123 will return true. (123f will still return false).

Be aware that technically an empty string is a 0-length string of digits, and so it will return true using ^[0-9]*$ If you want to only accept strings containing 1 or more digits, use + instead of *

^[0-9]+$

As the many others have pointed out, there are more than a few ways to achieve this, but I felt like it was appropriate to point out that the code in the original question only requires a single additional character to work as intended.

user1299656
  • 630
  • 1
  • 9
  • 15
27

This is extreme overkill for your purpose:

const numberReSnippet = "NaN|-?((\d*\.\d+|\d+)([Ee][+-]?\d+)?|Infinity)";
const matchOnlyNumberRe = new RegExp("^("+ numberReSnippet + ")$");

To my knowledge, this matches all the variations on numbers that Java and JavaScript will ever throw at you, including "-Infinity", "1e-24" and "NaN". It also matches numbers you might type, such as "-.5".

As written, numberReSnippet is designed to be dropped into other regular expressions, so you can extract (or avoid) numbers. Despite all the parentheses, it contains no capturing groups. Thus "matchOnlyNumberRe" matches only strings that are numbers, and has a capturing group for the entire string.

Here are the Jasmine tests, so you can see what it does and doesn't handle:

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);
    });
});
David Leppik
  • 3,194
  • 29
  • 18
  • IsNumber will only check if it's integer, as its name it should check if it's number in general (double, integer). I think this answer is more comprehensive than others. – Dabbas Aug 10 '17 at 10:59
  • 2
    The part `[E|e][+|-]?` is incorrect. It looks like you were thinking `(?:E|e)(?:\+|-)?` and forgot to drop the `|` when you made it into character sets. You need the `|` when you use groupings to specify alternatives, but in a character set, the listed choices are automatically alternatives to each other and `|` has no special meaning. So something like `[E|e]` allows `E`, `e` and the character `|`. – Louis Dec 28 '17 at 16:55
  • So the correct regex (without non-catching groups and double slashes) is: `/NaN|-?((\d*\.\d+|\d+)([Ee][+-]?\d+)?|Infinity)/`. I switched up the floats and ints so the expression gets more greedy. – Simon Zyx Dec 28 '21 at 14:13
  • Thanks; I've changed the regex to @SimonZyx's, and added a unit test to confirm that the original was buggy. – David Leppik Jan 05 '22 at 16:43
18

\d will not match the decimal point. Use the following for the decimal.

const re = /^\d*(\.\d+)?$/
'123'.match(re)       // true
'123.3'.match(re)     // true
'123!3'.match(re)     // false
Muhammad Adeel
  • 2,877
  • 1
  • 22
  • 18
  • Although a good remark, this regex will also match a string containing only dots (e.g. '.....'.match(re) //true" – Mihai Cicu Feb 04 '20 at 14:18
  • 2
    not everything shud be left to regex :) there are preconditions to preconditions, unknowns to unknowns. – Muhammad Adeel Feb 04 '20 at 15:21
  • 1
    nicely said, sir :) just as a followup, we can use `/^\d*(\.\d+)?$/` to have a better match for positive floating numbers – Mihai Cicu Feb 06 '20 at 13:00
11

This function checks if it's input is numeric in the classical sense, as one expects a normal number detection function to work.

It's a test one can use for HTML form input, for example.

It bypasses all the JS folklore, like tipeof(NaN) = number, parseint('1 Kg') = 1, booleans coerced into numbers, and the like.

It does it by rendering the argument as a string and checking that string against a regex like those by @codename- but allowing entries like 5. and .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' ));

Explanation of the regex:

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

The initial "^" and the final "$" match the start and the end of the string, to ensure the check spans the whole string. The "-?" part is the minus sign with the "?" multiplier that allows zero or one instance of it.

Then there are two similar groups, delimited by parenthesis. The string has to match either of these groups. The first matches numbers like 5. and the second .5

The first group is

\d+\.?\d*

The "\d+" matches a digit (\d) one or more times.
The "\.?" is the decimal point (escaped with "\" to devoid it of its magic), zero or one times.

The last part "\d*" is again a digit, zero or more times.
All the parts are optional but the first digit, so this group matches numbers like 5. and not .5 which are matched by the other half.

Thilina Sampath
  • 3,615
  • 6
  • 39
  • 65
Juan Lanus
  • 2,293
  • 23
  • 18
8

If you need just positive integer numbers and don't need leading zeros (e.g. "0001234" or "00"):

var reg = /^(?:[1-9]\d*|\d)$/;
Andrej
  • 1,679
  • 1
  • 26
  • 40
8

If the numbers aren't supposed to be absurdly huge, maybe use:

new RegExp(
    '^' +                           // No leading content.
    '[-+]?' +                       // Optional sign.
    '(?:[0-9]{0,30}\\.)?' +         // Optionally 0-30 decimal digits of mantissa.
    '[0-9]{1,30}' +                 // 1-30 decimal digits of integer or fraction.
    '(?:[Ee][-+]?[1-2]?[0-9])?' +   // Optional exponent 0-29 for scientific notation.
    '$'                             // No trailing content.
)

This tries to avoid some scenarios, just in case:

  • Overflowing any buffers the original string might get passed to.
  • Slowness or oddities caused by denormal numbers like 1E-323.
  • Passing Infinity when a finite number is expected (try 1E309 or -1E309).
jjrv
  • 4,211
  • 2
  • 40
  • 54
8

Why dont use something like:

$.isNumeric($(input).val())

Is jquery tested, and the most common case are checked

leonardo rey
  • 707
  • 7
  • 7
  • 1
    You ask why not just use jQuery. Here are reasons why not. 1. If your code is not already using jQuery, add jQuery only to check that values are numeric? I don't think so. 2. Suppose you already have a framework in place that tokenizes by running through a list of regular expressions. If you don't use a regular expression for numbers, you have to write a special case for it: iterate through the list of regular expressions and then also check with jQuery whether the token is numeric. Complicates the code. 3. If you need to allow for `NaN` or the infinities, `$.isNumeric` won't work. – Louis Dec 28 '17 at 16:08
  • 1
    It's 2018. Any response that suggests jQuery as the solution when it's not explicitly asked should be ignored. – mwilson Jun 26 '18 at 02:42
6

Maybe it works:

let a = "1234"
parseInt(a) == a // true
let b = "1234abc"
parseInt(b) == b // false
LPOPYui
  • 799
  • 1
  • 9
  • 17
5

Simple Regex javascript

var cnpj = "12.32.432/1-22";
var rCnpj = cnpj.replace(/\D/gm,"");
console.log(cnpj);

*Result:

1232432122

Checks for only numbers:

if(rCnpj === cnpj){
   return true;
}

Simple example

if("12.32.432/1-22".replace(/\D/gm,"").length > 0){
   console.log("Ok.");
}
srburton
  • 349
  • 3
  • 8
  • This answer does not check whether a string contains only numbers. Instead, it removes all characters but numbers. You can make your answer applicable to the question by checking to see if the resulting value is strictly equivalent to the original value: `original_value === resulting_value // Only Numbers`. – Grant Miller Jun 01 '18 at 15:23
  • Thank you! It has been altered. – srburton Jul 16 '19 at 14:47
5

You need the * so it says "zero or more of the previous character" and this should do it:

var reg = new RegExp('^\\d*$');
Mike Samuel
  • 118,113
  • 30
  • 216
  • 245
Eric Hodonsky
  • 5,617
  • 4
  • 26
  • 36
3

You could also use the following methods but be aware of their internal implementation and/or return values.

1A isNaN(+'13761123123123'); // returns true
1B isNaN(+'13761123123ABC'); // returns false

2A ~~'1.23'; // returns 1
2B ~~'1.2A'; // returns 0

For 1A & 1B the string is first type coerced using the + operator before being passed to the isNaN() function. This works because a number types that include non-numeric values return NaN. There are considerations with the isNaN()'s implementation details which is documented here. One consideration is if a boolean value is passed as isNaN(+false|true) are coerced to their numeric equivalents and thus false is returned but one might expect the function to return true since the boolean value isn't numeric in the sense of what we are testing.

For 2A & 2B it's worth noting that finding the complement of the number requires the given value in question to be within the range the values of a signed 32 bit integer which can be referenced in the spec.

My personal preference, although it could be argued to be less readable since they include the unary operator, is 1A & 1B because of the speed and conciseness.

Perf https://jsperf.com/numeric-string-test-regexvsisnan/1

swallace
  • 408
  • 1
  • 4
  • 16
0

I see you have already gotten a lot of answers, but if you are looking for a regular expression that can match integers and floating point numbers, this one will work for you:

var reg = /^-?\d*\.?\d+$/;
Progo
  • 3,452
  • 5
  • 27
  • 44
0

On input, if you want to filter out other characters and only show numbers in the input field, you could replace the value of the field on keyup:

    var yourInput = jQuery('#input-field');
    yourInput.keyup(function() {
        yourInput.val((yourInput.val().replace(/[^\d]/g,'')))
    })   
Peter Graham
  • 2,467
  • 2
  • 24
  • 29
-1

If you want to match the numbers with signed values, you can use:

var reg = new RegExp('^(\-?|\+?)\d*$');

It will validate the numbers of format: +1, -1, 1.

Paul Rooney
  • 20,879
  • 9
  • 40
  • 61
shasi kanth
  • 6,987
  • 24
  • 106
  • 158
-1
/^[\+\-]?\d*\.?\d+(?:[Ee][\+\-]?\d+)?$/
Richeve Bebedor
  • 2,138
  • 4
  • 26
  • 40
-2
var pattern = /[0-9!"£$%^&*()_+-=]/;

This tries to avoid some scenarios, just in case:

Overflowing any buffers the original string might get passed to. Slowness or oddities caused by denormal numbers like 1E-323. Passing Infinity when a finite number is expected (try 1E309 or -1E309).

Paul Rooney
  • 20,879
  • 9
  • 40
  • 61
-4

Number only regex (Updated)

 var reg = new RegExp('[^0-9]','g');
ooozguuur
  • 3,396
  • 2
  • 24
  • 42
  • 1
    it's should delete the '/' as new RegExp('[^0-9]','g'); – zztczcx May 24 '14 at 07:16
  • 4
    This regexp is wrong, as it is matching everything, but not numbers... You should remove `^` from square brackets if it has to do what you intended... And syntax is wrong as @vagabond mentioned it. – Setthase Jan 14 '15 at 12:51