Get amount from giver string using Regex [duplicate]
So i have this string:
val value = "\nValue is €2,927"
How can i parse this amount 2927
, of any currency, and convert it to double/int
?
This is what i have try:
println(value.replaceAll("d{5}", ""))
Edit:
€
could be any currency sign.
This may not be a definitive answer to your question (I'm not a Scala coder) but I think it'll be useful anyway, combined with other answers and comments.
You made me think about creating a regex to identify monetary amounts only, ignoring other numbers. This is what I came up with:
([$£€¥₹])?(\d{1,3}(?:[, ]?\d{1,3})?(?:.\d+)?)(?(1)|(kr\.?|Kč))
This example handles amounts pre-fixed with signs for dollars $
, GB pounds £
, Euro €
, Japanese Yen (or Chinas Yuan Renminbi (?)) ¥
or Indian rupees ₹
.
It also handles currencies with a post-fixed currency "symbol". In the example Swedish/Danish/Norwegian kronor kr
and Czech koruna Kč
.
The amount is always captured in capture group 2. A prefixed currency symbol is in group 1, and a postfixed in group 3. (I figured - what good is the amount if you don't know the currency.)
See it here at regex101, handling this text:
The cost of this car with a 3.5 litre engine, is €2,927.100, or $3 271.32. In Sweden that would be around 27000kr. I would have to work overtime for 215 days to save the money for that, even though my job in the Czech Republic pays 436.5Kč an hour, and I can save 10% percent of that. My buddy in Japan, bought one for ¥357014.83.
It starts by matching an optional currency sign. Then it matchers the amount, which can be formatted like any of ###
, ##,###
, ##,###,###.###
. After that it uses a regex condition - if the initial currency symbol was matched, it matches nothing -> done. If it wasn't matched, it tests for the post-fixed currency types.
The code (shooting from the hip here - no Scala experience what so ever, just a "googler"):
val value = "\nValue is €2,927"
val pattern = "([$£€¥₹])?(\\d{1,3}(?:[, ]?\\d{1,3})?(?:.\\d+)?)(?(1)|(kr\\.?|Kč))".r
val pattern(c1, amnt, c2) = value
// remove spaces and thousands-separators from the value
val str = amnt.replaceAll("[ ,]", "")
// convert it to an integer and/or double.
val i = str.toInt
val d = str.toDouble
Edit
Wow! This was a tough one to crack. I've now learnt that java regex doesn't support if-else
constructs. So here's an alternative, little bit more complicated alternative:
(?=[$£€¥₹])(.)(\d{1,3}(?:,\d{3})?(?:\.\\d+)?)|(\d{1,3}(?:,\d{3})?(?:\.\d+)?)(kr\.?|Kč)
It uses a positive look-ahead to determine if it's a pre-fixed, or a post-fixed currency symbol. The actual amount capturing had to be split into two groups depending on pre or post. So either currency is in group 1 and amount in 2, or amount in 3 and currency in 4.
And see functioning ;) code here at ideone.
Edit #2
Some new currencies and stuff added after comment.
(Rs.|[$£€¥₹])?\s*(\d{1,3}(?:[, ]?\d{1,3})?(?:.\d+)?)(?(1)|\s*(kr\.?|Kč|INR|€))
Here at regex101.