Use Python's re.findall() with an explicit numeric pattern to extract every matching number from a string. The correct pattern depends on whether the text contains signs, decimals, grouped thousands, scientific notation, or digits embedded in words. Regex lets you decide how each form is recognized instead of accepting one broad rule by accident.

Choose the number formats your text contains
Start with the smallest set of rules that covers your data. Each part of a regular expression can represent a different numeric feature:
| Input requirement | Pattern fragment | Behavior |
|---|---|---|
| Integers and decimals | (?:\d+(?:\.\d+)?|\.\d+) | Recognizes whole numbers, standard decimals, and bare decimals such as .5. |
| Optional sign | [+-]? | Allows a leading plus or minus before the numeric value. |
| Grouped thousands | \d{1,3}(?:,\d{3})+ | Keeps well-formed grouped values together, such as 1,000,000. |
| Scientific notation | (?:[eE][+-]?\d+)? | Includes an exponent such as 1e5 when that form is enabled. |
| Digits inside identifiers | No left-boundary check | Permits text such as item123 to produce 123. |
Put the grouped-thousands branch before the plain-integer branch so the complete grouped value has priority. Python's \d also matches Unicode decimal characters by default; pass flags=re.ASCII when the input should be restricted to ASCII digits.
Run the extraction in Python
- Create a Python 3 script and load the source. Import the standard-library re module and assign the original content to a variable named text. Keeping the whole source in one string allows the regex to find embedded numbers as well as standalone values.
- Define a combined numeric pattern. Use [+-]? for optional signs, a grouped-thousands alternative, a decimal alternative, and an optional exponent. The full pattern shown below supports these common forms in one pass.
- Collect all matches in their original order. Pass the pattern and source string to re.findall(). Add flags=re.ASCII if only ASCII digits should count.
- Print and inspect the matches before transforming them. The result is initially a list of strings. Review it against the source so unexpected sign, separator, or decimal behavior is caught before the values enter another script.
import re
text = "Revenue 1,250.50; adjustment -20; item123"
pattern = r"(?:[+-]?(?:(?:\d{1,3}(?:,\d{3})+|\d+)(?:\.\d+)?|\.\d+)(?:[eE][+-]?\d+)?)"
matches = re.findall(pattern, text, flags=re.ASCII)
print(matches)
The matches follow their order of appearance in the source. The re.ASCII flag affects Python's character classes; remove it when Unicode decimal digits should also be eligible.
Set sign and separator behavior explicitly
The combined pattern is permissive: it can pull digits out of identifiers and may interpret the minus in an expression such as 5-3 as part of a negative value. Those are separate parsing decisions, not failures in re.findall().
For arithmetic-like text, add a left-boundary check before the number:
pattern = r"(?<![\w.])(?:[+-]?(?:(?:\d{1,3}(?:,\d{3})+|\d+)(?:\.\d+)?|\.\d+)(?:[eE][+-]?\d+)?)"
This fixed-width lookbehind prevents a match from starting immediately after a word character or dot. In 5-3, the two values are returned without treating subtraction as a negative sign. A genuinely negative value after whitespace, an opening bracket, or a comparison can still retain its sign. The tradeoff is that identifiers such as item123 are no longer included; removing the boundary restores embedded digit runs but also restores permissive sign matching.
- Thousands separators: Keep the grouped branch when commas represent well-formed thousands grouping. If commas are ordinary delimiters, remove that branch so each digit run is extracted separately.
- Scientific notation: Retain the exponent branch only when values such as 1e5 should count as single numbers. Removing it excludes the exponent from the match.
- Embedded digits: Omit a restrictive left boundary when identifiers, product codes, or version strings should contribute their numeric portions.
Keep extracted values as text or convert them
re.findall() returns strings, which preserves source formatting such as leading signs, decimals, and grouped separators. Keep that form when copying values into a spreadsheet or comparing them with the original text. Convert only when arithmetic or another numeric operation requires it.
def to_number(value):
clean = value.replace(",", "")
return float(clean) if "." in clean or "e" in clean.lower() else int(clean)
numbers = [to_number(value) for value in matches]
This helper removes thousands separators before conversion, keeps ordinary integers as Python integers, and uses floating-point values for decimals and scientific notation. Binary floating-point arithmetic can introduce precision effects, so retain the original strings when exact formatting matters. To remove repeated matches while preserving first-seen order, use unique_matches = list(dict.fromkeys(matches)).
Use a browser extractor for visible rules and summaries
When a script is unnecessary, the Extract Numbers from Text tool provides the same core extraction task through visible controls. It runs entirely in your browser, so the pasted text is not uploaded, stored, or attached to an account.
- Paste the text containing the numbers. The extractor scans the complete input rather than requiring a preselected column or sentence.
- Adjust the parsing rules. Review the switches for signs, thousands separators, scientific notation, and de-duplication. Scientific notation is off by default because expressions such as 1e5 can occur in ordinary prose or identifiers.
- Choose the output and copy it. Select a list containing one number per line or comma-separated values, or select statistics for count, sum, minimum, maximum, and average. Check the reported number of matches before copying the result.
The browser tool uses an explicit sign-attachment rule rather than guessing from surrounding words. A minus is retained when genuinely attached in the documented contexts, so 5-3 produces 5 and 3 rather than 5 and -3. Well-formed grouping keeps 1,000,000 together, while malformed grouping splits at the malformation. De-duplication preserves the order of the first occurrence.
- ASCII only: Full-width digits and numerals from other scripts pass through unextracted.
- Auditable output: Every extraction reports how many numbers were found, and input containing no recognizable numbers is reported as exactly that rather than treated as an error.
- Statistics precision: Statistics use JavaScript double-precision arithmetic, so a sum of clean decimals can show residue around the fifteenth significant digit. The count remains exact.
- Input limit: Pasted input is capped at one million characters and processed in a single linear pass.
The tool extracts numeric content without interpreting it. It does not convert currencies, recognize units, parse dates, or infer what a number represents.
Validate edge cases before using the results
- Test each format in the source. Include a negative value, a decimal, a grouped number, an exponent if relevant, and any identifier whose digits should or should not count.
- Compare the count with the source. A count provides a quick audit, but it still needs to be checked against the expected number of values.
- Decide the ASCII policy. Python can match Unicode decimal digits when the ASCII flag is removed; the browser extractor intentionally recognizes ASCII digits only.
- Keep extraction separate from interpretation. Labels such as currency symbols, percentages, units, and dates may accompany a number, but the extractor does not convert or classify them.
For a Python workflow, use the pattern that matches your actual formats, inspect re.findall() results, and convert only at the next stage. For a no-code workflow with switchable rules and built-in summaries, paste the source into the browser extractor, verify the rules and found count, and copy the verified output.
For a deeper look, see Online Grocery Shopping Near Me: A Practical Local Plan.
For a deeper look, see Lorem Ipsum Generator Example: Practical Setups.