Regex for Extracting Numbers from a String — Integers, Decimals, and Negatives
Pulling numeric values out of free text — prices from product descriptions, quantities from chat messages, measurements from log lines — is a task every backend and scraping project runs into. This guide covers the regex for each numeric format you'll encounter.
Extracting Plain Integers
const text = 'Order #4521 has 3 items totaling 12 kg'; const integers = text.match(/\d+/g); console.log(integers); // ['4521', '3', '12'] — note these are strings, convert with Number() as needed
Extracting Decimals
const text = 'Price: 499.99, discount: 10.5%, rating 4.8 out of 5'; const decimals = text.match(/\d+\.?\d*/g); console.log(decimals); // ['499.99', '10.5', '4.8', '5']
Extracting Negative Numbers
A plain digit pattern ignores a leading minus sign — you need to explicitly allow it:
const text = 'Temperature dropped to -5.2°C, from a high of 21°C, change: -26.2'; const numbers = text.match(/-?\d+\.?\d*/g); console.log(numbers); // ['-5.2', '21', '-26.2']
Be careful: this pattern treats any digit sequence preceded directly by a hyphen as negative — including hyphens used as separators, like in order-42, which would incorrectly extract -42. Add a lookbehind or boundary check if your text contains hyphenated IDs.
// Safer: only treat '-' as a sign if preceded by whitespace, start of string, or another operator const safeNegative = /(?<![a-zA-Z0-9])-?\d+\.?\d*/g; 'order-42 costs -5.50'.match(safeNegative); // ['42', '-5.50'] — '-' in 'order-42' is correctly ignored as a sign
Extracting Numbers with Thousands Separators
const text = 'Revenue was ₹1,25,000 last month, up from ₹98,500'; // Indian numbering system uses irregular comma grouping (lakh/crore), // so match any digit-comma sequence and clean up afterward const raw = text.match(/[\d,]+/g); console.log(raw); // ['1,25,000', '98,500'] const asNumbers = raw.map((n) => Number(n.replace(/,/g, ''))); console.log(asNumbers); // [125000, 98500]
Note the Indian numbering system groups digits as 2-2-3 (lakh/crore style) rather than the Western 3-3-3 pattern, so a fixed \d{1,3}(,\d{3})* pattern built for Western grouping will not match Indian-formatted numbers like 1,25,000. Matching any digit-comma run and stripping commas afterward, as above, sidesteps that issue.
Converting Matches to Actual Numbers
function extractNumbers(text) {
const matches = text.match(/-?\d+\.?\d*/g) || [];
return matches.map(Number);
}
extractNumbers('3 apples cost 45.50, discount -5');
// [3, 45.5, -5]Common Pitfalls
- Forgetting matches are always strings — always wrap with
Number()orparseFloat() - Not handling the case where
match()returnsnullwhen there are zero matches — always default to an empty array - Trailing dots — a plain
\d+\.?\d*can match a lone trailing period as part of a sentence (e.g. "the total is 5."); tighten to\d+(\.\d+)?to require digits after the dot - Locale differences — some locales use a comma as the decimal separator instead of a dot; know your data source before choosing a pattern
Frequently Asked Questions
The pattern /-?\d+\.?\d*/g extracts integers, decimals, and negative numbers from mixed text in one pass using JavaScript's String.match method.
Use /-?\b\d+\b/g with word boundaries, or if you specifically need to avoid matching the integer part of a decimal number, use a negative lookahead: /-?\d+(?!\.\d)/g.
Not by default — a comma breaks the digit sequence. Use a pattern like /-?\d{1,3}(,\d{3})*(\.\d+)?/g to match numbers with comma thousands separators, then strip the commas before converting to a numeric type.