string-manipulation
number-extraction
programming
algorithms
text-processing

Find all numbers in the String

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Extracting all numbers from a string sounds simple, but requirements vary quickly once decimals, negative values, and thousand separators are involved. The best approach is to define what counts as a number first, then implement parsing rules that match that definition. For most cases, regular expressions plus type conversion are a reliable baseline.

Start with a Clear Number Definition

Before coding, decide whether your parser should accept:

  • integers only
  • signed values
  • decimal values
  • scientific notation
  • locale formatted values

A parser that works for log lines may fail for user entered finance data. Defining scope early avoids hidden parsing bugs.

Integer Extraction with Regex in Python

For positive integers, a simple pattern is enough.

python
1import re
2
3text = "Order 17 has 3 items and 2026 points"
4numbers = re.findall(r"\d+", text)
5values = [int(x) for x in numbers]
6print(values)  # [17, 3, 2026]

findall returns strings, so convert them to numeric types as needed.

Signed and Decimal Numbers

For broader numeric forms, use a more expressive pattern.

python
1import re
2
3text = "x=-12 y=3.14 z=.5 delta=-0.75"
4pattern = r"[+-]?(?:\d+\.\d+|\d+|\.\d+)"
5matches = re.findall(pattern, text)
6values = [float(m) for m in matches]
7print(values)  # [-12.0, 3.14, 0.5, -0.75]

This handles optional sign and decimal formats without requiring a leading digit for fraction values.

JavaScript Example

The same concept applies in JavaScript using global regex matches.

javascript
1const text = "Temp -3.5C, wind 12, pressure 1008";
2const pattern = /[+-]?(?:\d+\.\d+|\d+|\.\d+)/g;
3const values = (text.match(pattern) || []).map(Number);
4console.log(values); // [-3.5, 12, 1008]

Always guard against null from match when no numbers exist.

Avoiding Partial Matches

Naive patterns can capture fragments from version strings or identifiers. Use boundaries when needed.

python
1import re
2
3text = "version v1.2.3 id A123B value 45"
4numbers = re.findall(r"(?<![A-Za-z])\d+(?![A-Za-z])", text)
5print(numbers)  # ['1', '2', '3', '45']

If version numbers should stay grouped, parse them with a dedicated rule instead of a generic number extractor.

Locale and Formatted Numbers

Inputs like 1,234.50 require cleanup or locale aware parsing.

python
1import re
2
3text = "Revenue: 1,234.50 USD and cost: 987.40 USD"
4raw = re.findall(r"\d{1,3}(?:,\d{3})*(?:\.\d+)?", text)
5values = [float(x.replace(",", "")) for x in raw]
6print(values)  # [1234.5, 987.4]

For international inputs, consider locale libraries rather than hardcoding separators.

Performance for Large Text

For very large files, avoid reading everything into memory when possible. Stream line by line.

python
1import re
2
3pattern = re.compile(r"[+-]?(?:\d+\.\d+|\d+|\.\d+)")
4values = []
5
6with open("app.log", "r", encoding="utf-8") as f:
7    for line in f:
8        values.extend(float(m) for m in pattern.findall(line))
9
10print(len(values))

Compiled patterns also reduce repeated regex overhead.

Validation and Error Handling

Some matches may still fail conversion depending on pattern and input noise. Wrap conversion if input quality is uncertain.

python
1clean_values = []
2for token in matches:
3    try:
4        clean_values.append(float(token))
5    except ValueError:
6        pass

This keeps pipelines robust when data is messy.

Choosing Output Numeric Types

If downstream logic depends on integer arithmetic, convert only validated integer tokens to int and keep decimal tokens as float or Decimal. Mixing all values into floating point can introduce rounding drift in finance and measurement pipelines. Choosing output types intentionally is as important as matching tokens correctly.

Common Pitfalls

  • Using a simplistic digit pattern when signed or decimal values are required.
  • Forgetting to convert matched strings to numeric types before calculations.
  • Ignoring locale formatting and parsing comma separated numbers incorrectly.
  • Assuming match always returns data in JavaScript and skipping null checks.
  • Applying one regex to all domains where specialized token rules would be safer.

Summary

  • Define numeric formats before implementing extraction logic.
  • Use regex plus explicit conversion for most string parsing tasks.
  • Choose patterns that match your domain, not just generic digits.
  • Stream large inputs and compile regex for better performance.
  • Add validation steps when input quality is uncertain.

Course illustration
Course illustration

All Rights Reserved.