Jaki jest" najlepszy " RegEx waluty USA?

Szybkie wyszukiwanie waluty regex przynosi wiele wyników.

Problem, który mam przy wyborze jednego z nich jest to, że regex jest trudny do zweryfikowania bez testowania wszystkich przypadków krawędzi. Mógłbym poświęcić na to dużo czasu, ponieważ jestem pewien, że setki innych programistów już to zrobiły.

Czy ktoś ma regex dla waluty amerykańskiej, który został dokładnie przetestowany?

Moim jedynym wymogiem jest to, że dopasowany ciąg jest walutą USA i parsuje do systemu.Dziesiętne :

[ws][sign][digits,]digits[.fractional-digits][ws] 

Elements in square brackets ([ and ]) are optional. 
The following table describes each element. 

ELEMENT             DESCRIPTION
ws                  Optional white space.
sign                An optional sign.
digits              A sequence of digits ranging from 0 to 9.
,                   A culture-specific thousands separator symbol.
.                   A culture-specific decimal point symbol.
fractional-digits   A sequence of digits ranging from 0 to 9. 
Author: Leandro Tupone, 2008-12-09

11 answers

Oto kilka rzeczy od twórców Regex Buddy. Te pochodzą z biblioteki, więc jestem pewien, że zostały dokładnie przetestowane.

Liczba: kwota waluty (centy obowiązkowe) Opcjonalne separatory tysięcy; obowiązkowa dwucyfrowa frakcja

Match; JGsoft:
^[+-]?[0-9]{1,3}(?:,?[0-9]{3})*\.[0-9]{2}$

Number: Currency amount (cents optional) Opcjonalne separatory tysięcy; opcjonalne frakcja dwucyfrowa

Match; JGsoft:
^[+-]?[0-9]{1,3}(?:,?[0-9]{3})*(?:\.[0-9]{2})?$

Liczba: kwota waluty USA i UE (centy opcjonalne) 123 456,78 zł 123.456, 78 zł Opcjonalne separatory tysięcy; opcjonalne frakcja dwucyfrowa

Match; JGsoft:
^[+-]?[0-9]{1,3}(?:[0-9]*(?:[.,][0-9]{2})?|(?:,[0-9]{3})*(?:\.[0-9]{2})?|(?:\.[0-9]{3})*(?:,[0-9]{2})?)$
 76
Author: Keng,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-09 20:57:54

Znalazłem to wyrażenie regularne w linii na www.RegExLib.com autor: Kirk Fuller, Gregg Durishan

Używam go z powodzeniem od kilku lat.
"^\$?\-?([1-9]{1}[0-9]{0,2}(\,\d{3})*(\.\d{0,2})?|[1-9]{1}\d{0,}(\.\d{0,2})?|0(\.\d{0,2})?|(\.\d{1,2}))$|^\-?\$?([1-9]{1}\d{0,2}(\,\d{3})*(\.\d{0,2})?|[1-9]{1}\d{0,}(\.\d{0,2})?|0(\.\d{0,2})?|(\.\d{1,2}))$|^\(\$?([1-9]{1}\d{0,2}(\,\d{3})*(\.\d{0,2})?|[1-9]{1}\d{0,}(\.\d{0,2})?|0(\.\d{0,2})?|(\.\d{1,2}))\)$"
 12
Author: Dorababu Meka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-03 07:44:30

W ogóle nie do końca przetestowany (właśnie to napisałem!), ale wydaje się zachowywać poprawnie:

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

Zestaw testowy:

0
1
33
555
4,656
4656
99,785
125,944
7,994,169
7994169
0.00
1.0
33.78795
555.12
4,656.489
99,785.01
125,944.100
-7,994,169
-7994169.23 // Borderline...

Wrong:
000
01
3,3
5.
555,
,656
99,78,5
1,25,944
--7,994,169
0.0,0
.10
33.787,95
4.656.489
99.785,01
1-125,944.1
-7,994E169

Uwaga: Twój System.Decimal jest zależny od ustawień regionalnych, trudny do wykonania w wyrażeniach regularnych, chyba że przy jego budowaniu. Założyłem, że cyfry są pogrupowane przez trzy, nawet jeśli w niektórych kulturach (lokalizacjach) istnieją różne zasady.
Trywialne jest dodawanie białych spacji wokół niego.

 7
Author: PhiLho,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-09 21:52:01

ODPOWIEDŹ Kenga jest idealna, chcę tylko dodać, że do pracy z 1 lub 2 dziesiętnymi (dla trzeciej wersji):

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

NET FIDDLE: https://dotnetfiddle.net/1mUpX2

 3
Author: Leandro Tupone,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-15 19:16:44

To pytanie ma kilka lat, więc chciałem udzielić zaktualizowanej odpowiedzi.

Użyłem jQuery InputMask i działa bardzo dobrze dla maskowania wejścia / formatu (takich jak numery telefonów, itp.), ale tak naprawdę nie działa dobrze dla waluty z mojego doświadczenia.

Dla waluty, zdecydowanie polecam autoNumeric jQuery plugin. Jest dobrze utrzymany i w zasadzie "pomyśleli o wszystkim", czego mógłbym chcieć za walutę.

Właściwie używam kombinacji obu tych wtyczek do formatowania numerów telefonów, formatów numerów (ISBN itp.), a także walut (głównie waluta amerykańska).

Należy pamiętać, że jquery.inputmask polega głównie na kontrolowaniu formatu wartości, podczas gdy {[1] } polega na kontrolowaniu formatu waluty.

 1
Author: Dan L,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-12 02:54:49

Używam następującego wyrażenia regularnego do walidacji waluty:

^-?0*(?:\d+(?!,)(?:\.\d{1,2})?|(?:\d{1,3}(?:,\d{3})*(?:\.\d{1,2})?))$

Możesz również zezwolić na opcjonalny znak dolara wiodącego:

^\$?-?0*(?:\d+(?!,)(?:\.\d{1,2})?|(?:\d{1,3}(?:,\d{3})*(?:\.\d{1,2})?))$

Możesz łatwo dodać testowanie nawiasów zamiast znaku, dodając

\( and \)
 0
Author: eitanpo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-29 13:15:35

Też na to patrzyłem i doszedłem do wniosku, że najlepiej jest zbudować regex w oparciu o obecną kulturę. Możemy użyć

CurrencyPositivePattern 
CurrencyGroupSeparator
CurrencyDecimalSeparator

Właściwości NumberFormatInfo aby uzyskać wymagany format.

Edit: coś takiego

NumberFormatInfo nfi = CultureInfo.CurrentCulture.NumberFormat;
      // Assign needed property values to variables.
      string currencySymbol = nfi.CurrencySymbol;
      bool symbolPrecedesIfPositive = nfi.CurrencyPositivePattern % 2 == 0;
      string groupSeparator = nfi.CurrencyGroupSeparator;
      string decimalSeparator = nfi.CurrencyDecimalSeparator;

      // Form regular expression pattern.
      string pattern = Regex.Escape( symbolPrecedesIfPositive ? currencySymbol : "") + 
                       @"\s*[-+]?" + "([0-9]{0,3}(" + groupSeparator + "[0-9]{3})*(" + 
                       Regex.Escape(decimalSeparator) + "[0-9]+)?)" + 
                       (! symbolPrecedesIfPositive ? currencySymbol : ""); 

Refer - http://msdn.microsoft.com/en-us/library/hs600312.aspx

 0
Author: sidprasher,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-05 10:33:03

Udało mi się z tym (biorąc fragmenty z niektórych wyrażeń regularnych powyżej). Obsługuje tylko do tysięcy, ale nie powinno być zbyt trudne do rozszerzenia, że

case class CurrencyValue(dollars:Int,cents:Int)
def cents = """[\.\,]""".r ~> """\d{0,2}""".r ^^ {
  _.toInt
}
def dollarAmount: Parser[Int] = """[1-9]{1}[0-9]{0,2}""".r ~ opt( """[\.\,]""".r ~> """\d{3}""".r) ^^ {
  case x ~ Some(y) => x.toInt * 1000 + y.toInt
  case x ~ None => x.toInt
}
def usCurrencyParser = """(\$\s*)?""".r ~> dollarAmount ~ opt(cents) <~ opt( """(?i)dollars?""".r) ^^ {
  case d ~ Some(change) => CurrencyValue(d, change)
  case d ~ None => CurrencyValue(d, 0)
}
 0
Author: JoshMahowald,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-12 17:35:01

W przypadku, gdy chcesz wyjaśnić ludzki błąd, możesz sprawić, że regex będzie bardziej wybaczający przy dopasowywaniu waluty. Użyłem 2. ładnego regex Kenga i zrobiłem go nieco bardziej wytrzymałym, aby uwzględnić literówki.

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

To pasuje do każdej z tych poprawnych lub zniekształconych liczb walutowych, ale nie odbierze dodatkowych śmieci na końcu po spacji:

$46,48382
$4,648,382
$ 4,648,382
$4,648,382.20
$4,648,382.2
$4,6483,82.20
$46,48382 70.25PD
$ 46,48382 70.25PD
 0
Author: jim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-05 17:15:13

Tego używam:

Bez wiodącego + lub -

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

Z opcjonalnym prowadzeniem + lub -

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

Net fiddle: https://jsfiddle.net/compsult/9of63cwk/12/

 0
Author: MIkee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-07 21:41:50

Korzystając z odpowiedzi Leandro dodałem ^(?:[$]|) na początku, aby pozwolić na poprzedzający znak dolara

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

to dopasowane

136,402.99
25.27
0.33
$584.56
1
00.2
3,254,546.00
$3,254,546.00
00.01
-0.25
+0.85
+100,052.00

Nie Pasował

11124.52
234223425.345
234.
.5234
a
a.23
32.a
a.a
z548,452.22
u66.36
 0
Author: henrywright88404,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-29 00:49:34