help with a currency regular expression please

Mr Lucky

Well-known member
What I want is to match the value so a user must put in a currency symbol and amount

I can do this with a specific currency, e.g.

Code:
^\£(\d{1,3}(\,\d{3})*|(\d+))(\.\d{2})?$
for £

However I want to allow $ and € as well (or ideally any currency symbol)

Can someone please help with this?

Thanks
 
Update, yes, it tests fine, but just doesn't accept any currency symbol except $ when I try it live.

Mind providing the code you're using? I just did a quick dirty test and it seemed to work fine for any instance except using commas as the decimal separator
 
\p{Sc} will match any currency symbol if you have Unicode support enabled (/.../u or /(?u).../). Your other examples won't work without Unicode support because they're multi-byte in UTF-8; only $ will match properly. Others will end up matching a lot more characters than you're intending to match.

Here's an advanced locale-independent regex. Keep in mind that many locales swap the usage of "," and ".". Requires modifiers x and u.
Code:
(?(DEFINE)
  (?<currency_symbol> \p{Sc} )
  (?<leading_group> [1-9] \d{0,2}+ )
  (?<group> \d{3}+ )
  (?<non_leading_groups> (?&group) (?:(?&group_delim)(?&group))*+ )
  (?<decimal_delim>
    (?# Use the opposite of group_delim. )
    (?(group_delim_comma)
      \.
      | (?(group_delim_period)
        ,
        | [,.] (?# There's no definitive grouping_delim. )
      )
    )
  )
)

^
(?>
  (?&currency_symbol)
  (?&leading_group)
  (?:
    (?<group_delim>
      (?<group_delim_comma> , ) |
      (?<group_delim_period> \. ) |
      \  (?# Allow whitespace as a delimiter. )
    )
    (?&non_leading_groups)
    | \d*+ (?# It's also possible that there's no delimiter. )
  )
)
(?:
  (?&decimal_delim)
  \d*+
)?+
$

I've posted example test cases at https://regex101.com/r/wF8aJ6/.

In case you're one of those crazy people who likes to compress complex regexes into unreadable gibberish, here's the same thing in one line. Good luck reading it. ;)
Code:
/^(?>\p{Sc}[1-9]\d{0,2}+(?:(?<gd>(?<gdc>,)|(?<gdp>\.)|\ )\d{3}+(?:(?&gd)\d{3}+)*+|\d*+))(?:(?(gdc)\.|(?(gdp),|[,.]))\d*+)?+$/u
That one doesn't require modifier x, but I escaped the space in case anyone reading this accidentally uses it that modifier on it.
 
Last edited:
Tnaks, but that one doesn't seem to work either. The examples work at regex101, but not when I use for a match in a custom field on xenforo.
 
Code:
^(£|\$|€)(\d{1,3}(\,\d{3})*|(\d+))(\.\d{2})?$
Tested and works.

Requires the £, $, or € currency symbol.
 
Last edited:
Is this in a custom user field or a custom field in resource manager? It works in both places for me.

If not, how are you checking the regex?

EDIT: It also works in my Advanced Application Forms system.
 
Last edited:
Tnaks, but that one doesn't seem to work either. The examples work at regex101, but not when I use for a match in a custom field on xenforo.

You need to make sure the correct modifiers are applied. Try it like this:
Code:
(?u)^(?>\p{Sc}[1-9]\d{0,2}+(?:(?<gd>(?<gdc>,)|(?<gdp>\.)|\ )\d{3}+(?:(?&gd)\d{3}+)*+|\d*+))(?:(?(gdc)\.|(?(gdp),|[,.]))\d*+)?+$
 
Code:
^(£|\$|€)(\d{1,3}(\,\d{3})*|(\d+))(\.\d{2})?$
Tested and works.

Requires the £, $, or € currency symbol.

OK, I think I know the reason is it took a while for the cache on the site . So it is now working, thank you very much for that.

I have one more question about this.

How would a make an expression that requires either the £,$ € symbol OR a percentage?

So £20, €20, $20, 20% are all OK, but not 20.

Thanks
 
OK, I think I know the reason is it took a while for the cache on the site . So it is now working, thank you very much for that.

I have one more question about this.

How would a make an expression that requires either the £,$ € symbol OR a percentage?

So £20, €20, $20, 20% are all OK, but not 20.

Thanks
Code:
^(£|\$|€){1}(\d{1,3}(\,\d{3})*|(\d+))(\.\d{2})?$
This should require a symbol, I don't know what do you mean by requiring percentage?

Edit: Now I see what you mean, you have to add another regex match for the percentage like this:
Code:
^(\d{1,3}(\,\d{3})*|(\d+))(\.\d{2})?(%){1}$

So your PHP code should look like this:
PHP:
$pattern1 = '/^(£|\$|€){1}(\d{1,3}(\,\d{3})*|(\d+))(\.\d{2})?$/';
$pattern2 = '/^(\d{1,3}(\,\d{3})*|(\d+))(\.\d{2})?(%){1}$/';

if(preg_match($pattern1, $price) || preg_match($pattern2, $price))
{
    // Your code
}
 
Last edited:
How would I have two reggae matches for one field? I didn't know that as possible, so I wonder if it is possible to have one expression that covers currency symbols and the % sign?

Thanks
 
How would I have two reggae matches for one field? I didn't know that as possible, so I wonder if it is possible to have one expression that covers currency symbols and the % sign?

Thanks

Check my reply again, I have explained it with a PHP code.
 
Top Bottom