PatternRegex

Match a currency amount

Extract a priced amount, symbol and digits together, from receipts, invoices, or pasted text in dollars, euros, pounds, or rupees.

Last updated

Patterng
[₹$€£]\d{1,3}(?:,\d{3})*(?:\.\d+)?
Open in Regex Tester & Builder

Matches

  • Total: $1,250.00 due
  • Price is €99.99

Doesn’t match

  • Total is 1250.00 dollars
  • Symbol alone: $ and nothing else

Why it’s written this way

The leading character class [₹$€£] anchors the match to one of four common currency symbols sitting directly against the number, then \d{1,3}(?:,\d{3})* allows an optional run of comma-grouped thousands before an optional (?:\.\d+)? decimal tail.

Every quantifier after the symbol is optional or repeatable rather than fixed, so the same pattern matches a bare $5, a grouped $1,250, and a precise €99.99 without needing three separate rules.

Edge cases to know

  • →The symbol must sit directly against the digits — '$ 5' with a space in between, or the bare number followed by the word 'dollars', won't match.
  • →It doesn't validate that comma groups are exactly three digits apart the way a stricter thousands pattern would, so a malformed grouping like $1,2,345 still passes.
  • →Negative amounts and parenthesized accounting notation like ($50) aren't recognized — the pattern assumes a plain positive amount.

Part by part

[₹$€£]
A small set of currency symbols. It is a deliberate shortlist rather than an attempt at every currency — see the questions below.
\d{1,3}(?:,\d{3})*
The whole-number part with optional thousands separators. The star, unlike in the number pattern, allows a plain amount such as 50.
(?:\.\d+)?
Optional decimals. Left open rather than fixed at two, because prices with three or four decimal places do occur.

Common mistakes

  • \$\d+

    Handling one symbol and no separators misses most real amounts — anything with a comma stops at the first one, so $1,234 is reported as $1.

    [₹$€£]\d{1,3}(?:,\d{3})*(?:\.\d+)?
  • [₹$€£]?\d{1,3}(?:,\d{3})*(?:\.\d+)?

    Making the symbol optional turns a currency pattern into a number pattern, so every figure in the document matches and the result no longer answers the question you asked.

  • [₹$€£]\d{1,3}(?:,\d{3})*(?:\.\d{2})?

    Fixing the decimals at two rejects three-decimal fuel prices and four-decimal exchange rates, and truncates rather than failing — so $1.2345 quietly matches as $1.23.

Questions

Why only four currency symbols?

Because a complete list runs to well over a hundred and many currencies use plain letter codes instead. Add the symbols your data actually contains — a short, honest list beats an incomplete pretence at universality.

What about amounts written as USD 100 or 100 EUR?

Not matched. Letter codes are a different shape and can sit on either side of the number, so they need their own alternative — typically a three-letter uppercase code with optional whitespace.

Does it match a symbol after the number?

No. Several European locales write 100 € with the symbol trailing, and this pattern requires it in front. Add a second alternative rather than making the symbol position optional, which would loosen it too far.

Should I use this to parse money for calculations?

Only to find the text. Convert to an integer number of minor units — cents or paise — before doing arithmetic, because floating point cannot represent most decimal amounts exactly and errors accumulate.

Related in Patterns