PassionateDeveloper
PassionateDeveloper

Reputation: 15138

RegEx for Prices?

I am searching for a RegEx for prices. So it should be X numbers in front, than a "," and at the end 2 numbers max.

Can someone support me and post it please?

Upvotes: 21

Views: 71990

Answers (14)

Huda
Huda

Reputation: 1

^((\d+)((,\d+|\d+)*)(\s*|\.(\d{2}))$)

Matches:

1
11
111
1111111
11,2122
1222,21222
122.23
1223,3232.23

Not Matches:

11e
x111
111,111.090
1.000

Upvotes: 0

Ankur Gupta
Ankur Gupta

Reputation: 26

\d+((,\d+)+)?(.\d+)?(.\d+)?(,\d+)?

to cover all

  • 5

    5.00

    1,000

    1,000,000.99

    5,99 (european price)

    5.999,99 (european price)

    0.11

    0.00

Upvotes: 1

Chiradip Mandal
Chiradip Mandal

Reputation: 31

This one reasonably works when you may or may not have decimal part but an amount shows up like this 100,000 - or 100,000.00. Tested using Clojure only

\d{1,3}(?:[.,]\\d{3})*(?:[.,]\d{2,3})

Upvotes: 0

Praveen K P
Praveen K P

Reputation: 11

r'(^\-?\d*\d+.?(\d{1,2})?$)'

This will allow digits with only one decimal and two digits after decimal

Upvotes: 0

Scott Paterson
Scott Paterson

Reputation: 406

Pretty simple for "," separated numbers(Or no seperation) with 2 decimal places , supports deliminator but does not force them. Needs some improvement but should work.

^((\d{1,3}|\s*){1})((\,\d{3}|\d)*)(\s*|\.(\d{2}))$

matches:
    1,123,456,789,134.45
    1123456134.45
    1234568979
    12,345.45
    123.45
    123
no match:
    1,2,3
    12.4
    1234,456.45

This may need some editing to make it function correctly

Quick explanation: Matches 1-3 numbers(Or nothing), matches a comma followed by 3 numbers as many times as needed(Or just numbers), matches a decimal point followed by 1 or 2 numbers(Or Nothing)

Upvotes: 1

Meangczac
Meangczac

Reputation: 474

So far I tried, this is the best

\d{1,3}[,\\.]?(\\d{1,2})?

https://regex101.com/r/xT8aQ7/1

Upvotes: 0

HoQuocThinh
HoQuocThinh

Reputation: 21

This code worked for me !! (PHP)

preg_match_all('/\d+((,\d+)+)?(.\d+)?(.\d+)?(,\d+)?/',$price[1]->plaintext,$lPrices);

Upvotes: 0

r-hold
r-hold

Reputation: 1120

I am working on similar problem. However i want only to match if a currency Symbol or String is also included in the String like EUR,€,USD or $. The Symbol may be trailing or leading. I don't care if there is space between the Number and the Currency substring. I based the Number matching on the previous discussion and used Price Number: \d{1,3}(?:[.,]\d{3})*(?:[.,]\d{2})?

Here is final result:

(USD|EUR|€|\$)\s?(\d{1,3}(?:[.,]\d{3})*(?:[.,]\d{2}))|(\d{1,3}(?:[.,]\d{3})*(?:[.,]\d{2})?)\s?(USD|EUR|€|\$)

I use (\d{1,3}(?:[.,]\d{3})*(?:[.,]\d{2})?)\s?(USD|EUR|€|\$) as a pattern to match against a currency symbol (here with tolerance for a leading space). I think you can easily tweak it for any other currencies

A Gist with the latest Version can be found at https://gist.github.com/wischweh/b6c0ac878913cca8b1ba

Upvotes: 11

elgehelge
elgehelge

Reputation: 2150

I was not satisfied with the previous answers. Here is my take on it:

\d{1,3}(?:[.,]\d{3})*(?:[.,]\d{2})

|^^^^^^|^^^^^^^^^^^^^|^^^^^^^^^^^|
| 1-3  | 3 digits    | 2 digits  |
|digits| repeat any  |           |
|      | no. of      |           |
|      | times       |           |

(get a detailed explanation here: https://regex101.com/r/cG6iO8/1)

Covers all cases below

  • 5.00
  • 1,000
  • 1,000,000.99
  • 5,99 (european price)
  • 5.999,99 (european price)
  • 0.11
  • 0.00

But also weird stuff like

  • 5.000,000.00

In case you want to include 5 and 1000 (I personally wound not like to match ALL numbers), then just add a "?" like so:

\d{1,3}(?:[.,]\d{3})*(?:[.,]\d{2})?

Upvotes: 23

Tobliug
Tobliug

Reputation: 3042

I am currently working on a small function using regex to get price amount inside a String :

private static String getPrice(String input)
{
    String output = "";

    Pattern pattern = Pattern.compile("\\d{1,3}[,\\.]?(\\d{1,2})?");
    Matcher matcher = pattern.matcher(input);
    if (matcher.find())
    {
        output = matcher.group(0);
    }

    return output;
}

this seems to work with small price (0,00 to 999,99) and various currency :

$12.34 -> 12.34

$12,34 -> 12,34

$12.00 -> 12.00

$12 -> 12

12€ -> 12

12,11€ -> 12,11

12.999€ -> 12.99

12.9€ -> 12.9

£999.99€ -> 999.99

...

Upvotes: 1

Samwhoo
Samwhoo

Reputation: 312

So I ran into a similar problem, needing to validate if an arbitrary string is a price, but needed a lot more resilience than the regexes provided in this thread and many other threads.

I needed a regex that would match all of the following:

  • 5
  • 5.00
  • 1,000
  • 1,000,000.99
  • 5,99 (european price)
  • 5.999,99 (european price)
  • 0.11
  • 0.00

And not to match stuff like IP addresses. I couldn't figure out a single regex to deal with the european and non-european stuff in one fell swoop so I wrote a little bit of Ruby code to normalise prices:

if value =~ /^([1-9][0-9]{,2}(,[0-9]{3})*|[0-9]+)(\.[0-9]{1,9})?$/
  Float(value.delete(","))
elsif value =~ /^([1-9][0-9]{,2}(\.[0-9]{3})*|[0-9]+)(,[0-9]{1,9})?$/
  Float(value.delete(".").gsub(",", "."))
else
  false
end

The only difference between the two regexes is the swapped decimal place and comma. I'll try and break down what this is doing:

/^([1-9][0-9]{,2}(,[0-9]{3})*|[0-9]+)(\.[0-9]{1,9})?$/

The first part:

([1-9][0-9]{,2}(,[0-9]{3})*

This is a statement of numbers that follow this form: 1,000 1,000,000 100 12. But it does not allow leading zeroes. It's for the properly formatted numbers that have groups of 3 numerics separated by the thousands separator.

Second part:

[0-9]+

Just match any number 1 or more times. You could make this 0 or more times if you want to match: .11 .34 .00 etc.

The last part:

(\.[0-9]{1,9})?

This is the decimal place bit. Why up to 9 numerics, you ask? I've seen it happen. This regex is supposed to be able to handle any weird and wonderful price it sees and I've seen some retailers use up to 9 decimal places in prices. Usually all 0s, but we wouldn't want to miss out on the data ^_^

Hopefully this helps the next person to come along needing to process arbitrarily badly formatted price strings or either european or non-european format :)

Upvotes: 4

anon
anon

Reputation: 1

anything like \d+,\d{2} is wrong because the \d matches [0-9\.] i.e. 12.34,1.

should be: [0-9]+,[0-9]{2} (or [0-9]+,[0-9]{1,2} to allow only 1 decimal place)

Upvotes: -4

Andrea Ambu
Andrea Ambu

Reputation: 39516

In what language are you going to use it?

It should be something like:

^\d+(,\d{1,2})?$

Explaination:

X number in front is: ^\d+ where ^ means the start of the string, \d means a digit and + means one or more

We use group () with a question mark, a ? means: match what is inside the group one or no times.

inside the group there is ,\d{1,2}, the , is the comma you wrote, \d is still a digit {1,2} means match the previous digit one or two times.

The final $ matches the end of the string.

Upvotes: 35

Matthew Scharley
Matthew Scharley

Reputation: 132254

^\d+,\d{1,2}$

Upvotes: 3

Related Questions