Home >Blog

Regex for Numbers Only: Integers, Decimals, Negative Values, and Leading Zeros

Published Updated

“Numbers only” sounds like a small validation rule, but the right regex depends on the number format you actually want to accept. A field may allow plain integers, decimal values, negative amounts, commas, or leading zeros. Those choices are different grammars. A pattern that is correct for 42 may reject -42, and a pattern that accepts 1,234.50 may also accept a badly placed comma unless it is written carefully.

This guide builds the patterns one step at a time. It covers ASCII digits, Unicode behavior, whole numbers, decimals, signed values, thousands separators, and leading zeros. The examples use JavaScript and Python, with copy-ready snippets you can adapt to a form, search box, import script, or API boundary.

The basic regex for numbers only

If “numbers only” means one or more ASCII digits and nothing else, start here:

^[0-9]+$

The anchors require the entire input to match. [0-9] matches one digit from 0 through 9, and + requires at least one of them. The pattern accepts 0, 7, and 2026. It rejects an empty string, spaces, a decimal point, a minus sign, and letters.

You will also see this shorter version:

^\d+$

It is often fine, but \d is not identical in every regex engine. If your application has to accept ASCII digits only, [0-9] makes that policy visible and predictable.

\d versus [0-9]: the Unicode detail

In JavaScript without special Unicode property escapes, \d matches the ASCII digits 0–9. The same is true for the common JavaScript form /^\d+$/. Python is different: the default re behavior treats \d as a Unicode decimal-digit category, so it can match characters such as Arabic-Indic digits. Python’s [0-9] remains the explicit ASCII range.

That difference matters when a value is sent to a system that expects ordinary ASCII text, when you convert the match with an older parser, or when a database field has a strict input contract. Use the narrowest rule that matches your requirements:

ASCII digits in any engine:
^[0-9]+$

JavaScript digits:
/^\d+$/

Python ASCII digits:
re.fullmatch(r"[0-9]+", value)

Python Unicode decimal digits:
re.fullmatch(r"\d+", value)

In Python, you can also use the re.ASCII flag if you want shorthand classes such as \d to use ASCII semantics. Do not assume that moving a pattern from Python to JavaScript, or from one library to another, preserves every character-class rule.

Regex for non-negative integers

A non-negative integer has no decimal point and no sign. The basic pattern is the same as the numbers-only pattern:

^[0-9]+$

Use this for quantities, page numbers, counts, or an ID field when zero is allowed. If zero is not valid and the value must be positive, require a non-zero first digit:

^[1-9][0-9]*$

This accepts 1, 25, and 9000, but rejects 0 and 007. That last result is intentional for a canonical positive integer. If leading zeros are part of the format, use a different pattern rather than adding a loose optional group.

Regex for decimals

For a non-negative decimal with digits on both sides of the decimal point, use:

^[0-9]+\.[0-9]+$

It accepts 12.50 and 0.75, while rejecting 12, .75, and 12.. Requiring digits on both sides is a useful default for data exchanged between systems.

If your UI should accept either an integer or a decimal, make the decimal part optional:

^[0-9]+(?:\.[0-9]+)?$

To limit the value to two decimal places, change the final group to {1,2}:

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

This controls the shape, not the numeric range. It accepts 999999.99 just as readily as 9.99. Check maximum and minimum values in code after the regex succeeds.

Allowing negative numbers and an optional plus sign

To allow negative or positive integers, put an optional sign at the beginning:

^[+-]?[0-9]+$

The character class [+-] means either plus or minus. The question mark makes the sign optional. This accepts -42, +42, and 42. If plus signs should be rejected but negative values are allowed, use -? instead:

^-?[0-9]+$

For signed decimals, combine the same sign prefix with the decimal rule:

^[+-]?[0-9]+(?:\.[0-9]+)?$

Keep a policy decision in mind: should -0 be accepted? Regex sees it as a valid sign followed by digits. If negative zero has a special meaning in your application, handle that after matching.

Thousands separators and formatted numbers

For comma-separated groups in the familiar US style, a strict pattern is:

^[+-]?(?:[0-9]+|[0-9]{1,3}(?:,[0-9]{3})+)(?:\.[0-9]+)?$

The first alternative accepts an unformatted number such as 1234.50. The second accepts correctly grouped values such as 1,234 and 12,345,678.90. The comma group repeats only after an initial group of one to three digits, so malformed values such as 1,23, 12,34,567, and 1,2345 fail.

If commas are required for values with four or more integer digits, use a stricter version:

^[+-]?[0-9]{1,3}(?:,[0-9]{3})+(?:\.[0-9]+)?$

Formatting conventions vary by locale. European input may use a period for grouping and a comma for decimals, while some locales use a narrow no-break space. Do not silently treat every comma as a thousands separator. Parse the locale deliberately, or normalize a known format before numeric conversion.

Leading zeros: decide what they mean

Leading zeros are not automatically wrong. They may be required for an account code, a two-digit month, or a fixed-width identifier. They are usually unwanted when the field represents a canonical number.

For an integer with no leading zeros except the value zero itself, use:

^(?:0|[1-9][0-9]*)$

This accepts 0, 7, and 105, but rejects 00 and 007. For exactly two digits, including values such as 07, use ^[0-9]{2}$. For a fixed three-digit code, use ^[0-9]{3}$. These patterns describe a code, not a number that should be converted without preserving its text.

JavaScript examples

JavaScript regex literals are convenient for one-off checks. Use test() for a boolean result and trim only if surrounding whitespace is allowed by your input contract.

const integerOnly = /^[0-9]+$/;
const signedDecimal = /^[+-]?[0-9]+(?:\.[0-9]+)?$/;

integerOnly.test("42");       // true
integerOnly.test("42.5");     // false
signedDecimal.test("-42.5");  // true
signedDecimal.test(" 42.5");  // false

When using new RegExp(), remember that the JavaScript string literal processes backslashes first:

const pattern = new RegExp("^[+-]?[0-9]+(?:\\.[0-9]+)?$");
const valid = pattern.test(value);

The regex engine must receive \. to match a literal dot, so the string source contains \\.. A regex literal avoids that extra layer of escaping.

Python examples

Python raw strings make regex code easier to read because most backslashes are passed through unchanged. For full-string validation, re.fullmatch() expresses the intent directly.

import re

integer_only = re.compile(r"[0-9]+")
signed_decimal = re.compile(r"[+-]?[0-9]+(?:\.[0-9]+)?")

integer_only.fullmatch("42")       # Match object
integer_only.fullmatch("42.5")     # None
signed_decimal.fullmatch("-42.5")  # Match object

If you intentionally want Unicode decimal digits in Python, compile r"\d+" without re.ASCII. If you want the shorthand to behave like ASCII, write re.fullmatch(r"\d+", value, flags=re.ASCII), or use [0-9]+ and make the rule obvious.

Copy-ready regex reference

ASCII digits only:
^[0-9]+$

Positive integer, no leading zeros:
^[1-9][0-9]*$

Integer with zero allowed, no extra leading zeros:
^(?:0|[1-9][0-9]*)$

Unsigned decimal:
^[0-9]+\.[0-9]+$

Integer or decimal:
^[0-9]+(?:\.[0-9]+)?$

Signed integer:
^[+-]?[0-9]+$

Signed decimal:
^[+-]?[0-9]+(?:\.[0-9]+)?$

Two decimal places maximum:
^[+-]?[0-9]+(?:\.[0-9]{1,2})?$

US-style grouped number:
^[+-]?(?:[0-9]+|[0-9]{1,3}(?:,[0-9]{3})+)(?:\.[0-9]+)?$

Why full-string matching matters

Validation and searching are different jobs. A pattern such as [0-9]+ can find a run of digits inside Room 42, but that does not mean the complete value is numeric. For validation, anchor the pattern or use an API that explicitly performs a full match. In most regex flavors, ^ marks the beginning and $ marks the end. The anchors turn a substring search into a whole-input check.

There is one newline detail worth testing. Some engines let $ match just before a final newline, which can make an input containing 42\n look valid. If your environment supports an absolute-end anchor such as \z, use the engine-specific option when you need that strictness. In JavaScript, checking the value after removing an allowed line ending, or using a full-input comparison in application code, makes the policy clearer. Do not add a multiline flag to a validation regex unless you specifically want each line to be checked independently.

Examples of accepted and rejected values

A short test matrix is often more useful than a complicated pattern. The table below assumes that the rule is ASCII digits only, with no signs, spaces, decimal points, or separators. When your product changes that policy, update both the regex and its tests.

InputDigits-only resultReason
42AcceptASCII digits only
0AcceptZero is a digit sequence
007AcceptLeading zeros are not excluded
-42RejectContains a minus sign
42.5RejectContains a decimal point
42 RejectContains surrounding spaces

Whitespace, empty values, and normalization

Decide what to do with whitespace before writing the pattern. A web form may receive a value copied with a trailing space, while an API may require the client to send an exact token. If spaces are allowed around a number, normalize first and validate the normalized value; for example, trim the string once, then apply ^[+-]?[0-9]+$. If spaces are meaningful or should produce an error, do not hide them with a broad expression such as \s*.

Empty input is another separate rule. The quantifier + requires at least one character, while * also accepts an empty string. For a required field, keep + and report “required” separately from “invalid number.” For an optional field, check for an empty value before running the numeric regex. This produces clearer error messages and avoids accidentally treating a missing value as zero.

Validation versus extraction

Do not use a validation pattern as an extraction pattern without changing the surrounding logic. For example, \d+ can extract 123 from Order 123A, but a numbers-only field should reject the whole string. Conversely, a strict anchored pattern may be the wrong tool when you are intentionally finding every number in a sentence. Choose anchors, capture groups, and iteration based on whether the task is “is this value valid?” or “where are the numbers?”

Frequently asked questions

What is the simplest regex for numbers only? For one or more ASCII digits, use ^[0-9]+$. It does not allow signs, decimal points, commas, or whitespace.

Should I use \d or [0-9]? Use [0-9] when the input contract requires ASCII digits. It avoids relying on engine-specific Unicode behavior. Use \d only when you have checked the target engine and intentionally want its digit semantics.

Can regex check whether a number is between two values? It can describe small, fixed ranges, but range expressions become difficult to maintain quickly. Match the permitted format with regex, then parse the value and compare it numerically in code.

Why does my decimal regex reject .5? A pattern using [0-9]+\.[0-9]+ requires digits on both sides of the dot. If your interface deliberately accepts .5, use a separate optional-integer-part rule and test that format explicitly.

Regex validation is only the first check

A regex can confirm the spelling of a value. It does not safely replace numeric parsing. After a match, convert the value using the language’s number type, check the allowed range, decide how to handle whitespace, and consider whether floating-point precision is suitable for money. For monetary values, a decimal library or integer minor-unit representation is often safer than a binary floating-point number.

Test the edge cases your product actually accepts: empty input, zero, a negative value, a decimal with too many places, a misplaced separator, a trailing newline, and non-ASCII digits. Keep the regex small enough that another developer can tell what policy it implements. The best “numbers only” regex is the one whose accepted formats match the rest of your application.

FAQ

What is the simplest regex for numbers only?
For ASCII digits only, use ^[0-9]+$. The anchors require the entire input to contain one or more digits, so letters, spaces, punctuation, and an empty value are rejected.
Should I use \d or [0-9] for numbers-only validation?
Use [0-9] when the accepted format must be ASCII digits. Depending on the regex engine and Unicode settings, \d can match additional Unicode decimal digits. Choose \d only when that broader behavior is intentional.
How can I allow decimals and negative numbers?
Define the exact format before writing the pattern. For a signed decimal with an optional fractional part, use ^[+-]?[0-9]+(?:\.[0-9]+)?$. If a leading decimal point is allowed, use a different branch such as ^[+-]?(?:[0-9]+(?:\.[0-9]+)?|\.[0-9]+)$.
Can regex validate commas and numeric ranges?
Regex can validate a string shape such as 1,234.56, but it is not a substitute for numeric parsing. After the format check, parse the value and apply business rules such as minimum, maximum, or precision.

Table of Contents

Information

  • Hits211
  • Published date2026/09/12
0/500
Share your thoughts respectfully.

More Posts

Explore more articles from this section
Regex for IP Addresses: Accurate IPv4 and IPv6 Validation Examples
Sep 09, 2026286views

Regex for IP Addresses: Accurate IPv4 and IPv6 Validation Examples

Use regex to find possible IP addresses, then use the right validation rule for the job. This guide covers loo...

#regex for IP address#IP address regex#IPv4 regex#IPv6 regex
Password Validation Regex: Examples for Length, Numbers, Symbols, and Strong Passwords
Sep 07, 2026268views

Password Validation Regex: Examples for Length, Numbers, Symbols, and Strong Passwords

Learn practical password validation regex patterns for length, digits, symbols, and mixed character classes. T...

#password validation regex#regex for password validation#strong password regex#regex lookahead
What Regex Should You Use for Phone Numbers? Patterns for US and International Formats
Aug 28, 2026256views

What Regex Should You Use for Phone Numbers? Patterns for US and International Formats

Compare practical regex patterns for US formatted numbers, normalized local numbers, plus-prefixed internation...

#phone number regex#regex for phone number#US phone regex#international phone regex
How to Validate a URL with Regex: HTTP, HTTPS, Domains, and Query Strings
Sep 03, 2026245views

How to Validate a URL with Regex: HTTP, HTTPS, Domains, and Query Strings

Build a practical HTTP and HTTPS URL regex by separating schemes, DNS domains, ports, paths, query strings, an...

#URL validation regex#regex for URL validation#HTTP URL regex#HTTPS URL regex
How to Extract Email Addresses from Text with Regex in Python and JavaScript
Sep 15, 2026210views

How to Extract Email Addresses from Text with Regex in Python and JavaScript

Extract email addresses from any text with regex in Python and JavaScript: the pattern explained piece by piec...

#regex extract email#email regex python#email regex javascript#extract emails from text
What Is the Best Regex for Email Validation? Practical Patterns and Limitations
Aug 31, 2026208views

What Is the Best Regex for Email Validation? Practical Patterns and Limitations

Choose a simple or practical email-validation regex based on your input policy, compare JavaScript and Python ...

#email validation regex#regex for email validation#email regex#JavaScript regex
Feedback email