How to extract numbers from text with regex
The patterns for integers, decimals, negatives, currency, and scientific notation — with side-by-side comparisons.
The short answer
For simple integers in a string:
\d+
For most real-world cases (including decimals and negatives):
-?\d+(\.\d+)?
Use matchAll in JavaScript or findall in Python to get all occurrences.
The four common cases
1. Just digits
Pattern: \d+
Input: "Order #12345 shipped on day 7"
Matches: ["12345", "7"]
Use this when you know there are no decimals or signs to worry about.
2. Decimals (and integers)
Pattern: \d+(\.\d+)?
Input: "Order $24.99 ships in 3 days"
Matches: ["24.99", "3"]
The (\.\d+)? says: optionally, a dot followed by more digits. Use this for prices, measurements, and other decimal data.
3. Negatives included
Pattern: -?\d+(\.\d+)?
Input: "Temperature: -12.5°C; humidity: 80"
Matches: ["-12.5", "80"]
4. Scientific notation
Pattern: -?\d+(\.\d+)?([eE][+-]?\d+)?
Input: "Avogadro: 6.022e23"
Matches: ["6.022e23"]
JavaScript example
const text = "Order #12345 totalling $24.99 ships in 3 days";
const numbers = [...text.matchAll(/-?\d+(\.\d+)?/g)].map(m => parseFloat(m[0]));
// [12345, 24.99, 3]
Python example
import re
text = "Order #12345 totalling $24.99 ships in 3 days"
numbers = [float(m) for m in re.findall(r"-?\d+(?:\.\d+)?", text)]
# [12345.0, 24.99, 3.0]
Gotchas
The minus sign isn't always a negative
-12 in "car-12-door" isn't a negative number — the hyphen is a separator. If you want only true negatives (preceded by whitespace, start of string, or specific characters), use a lookbehind:
(?<=^|\s)-?\d+(\.\d+)?
Dots aren't always decimals
Version numbers like 1.2.3 match 1.2 with the decimal pattern, leaving .3 behind. If your text has version numbers or IP addresses, use word boundaries:
\b\d+(\.\d+)?\b
Commas as thousand separators
For European/US numbers like 1,000,000 or 1.000.000, the pattern needs to handle the separators:
\d{1,3}(,\d{3})*(\.\d+)? US: 1,234.56
\d{1,3}(\.\d{3})*(,\d+)? EU: 1.234,56
Currency symbols
If you want the amount including symbol:
[$€£¥]?\s*-?\d+(\.\d+)?
The takeaway
For 80% of cases, -?\d+(\.\d+)? is the right pattern. Add features one at a time as you encounter them — don't reach for the kitchen-sink pattern that handles every case until you actually need to.
For complex parsing (currency strings with locale-specific separators, scientific notation, percentages), parse after the match: use regex to find the number-shaped string, then use a real parser to convert.
Related reading
Try this pattern in the explainer
Paste any regex into the live explainer and see what each token means, with example matches in real time.
Open the regex explainer →