Quel est le" meilleur " RegEx de monnaie américaine?

Une recherche rapide de la monnaie regex amène beaucoup de résultats.

Le problème que j'ai En choisissant l'un d'entre eux est que regex est difficile à vérifier sans tester tous les cas de bord. Je pourrais passer beaucoup de temps à ce sujet car je suis sûr que des centaines d'autres développeurs l'ont déjà fait.

Est-ce que quelqu'un a une regex pour la devise américaine qui a été soigneusement testée?

Ma seule exigence est que la chaîne correspondante soit la devise américaine et que analyse pour le Système.Décimal :

[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. 
44
demandé sur Leandro Tupone 2008-12-09 23:05:33

11 réponses

Voici quelques trucs des créateurs de Regex Buddy. Ceux-ci sont venus de la bibliothèque, donc je suis convaincu qu'ils ont été soigneusement testés.

Nombre: montant de la devise (cents obligatoire) Séparateurs de milliers facultatifs; fraction obligatoire à deux chiffres

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

Nombre: montant de la devise (cents en option) Séparateurs de milliers facultatifs; fraction à deux chiffres facultative

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

Nombre: montant de la devise US & EU (cents en option) Peut utiliser us-style 123,456.78 notation et de style européen 123.456, 78 notation. Séparateurs de milliers facultatifs; fraction à deux chiffres facultative

Match; JGsoft:
^[+-]?[0-9]{1,3}(?:[0-9]*(?:[.,][0-9]{2})?|(?:,[0-9]{3})*(?:\.[0-9]{2})?|(?:\.[0-9]{3})*(?:,[0-9]{2})?)$
76
répondu Keng 2008-12-09 20:57:54

J'ai trouvé cette expression régulière en ligne à www.RegExLib.com il s'agit de la première version de la série.]}

Je l'utilise avec succès depuis quelques années.

"^\$?\-?([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
répondu Dorababu Meka 2011-08-03 07:44:30

Pas complètement testé du tout (je viens de l'écrire!), mais semble se comporter correctement:

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

Jeu D'essai:

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

Remarque: Votre Système.Decimal dépend des paramètres régionaux, difficile à faire dans regex, sauf peut-être lors de la construction. J'ai supposé que les chiffres étaient regroupés par trois, même si dans certaines cultures (locales) il y a des règles différentes.
Il est trivial d'ajouter des espaces autour d'elle.

7
répondu PhiLho 2008-12-09 21:52:01

La réponse de Keng est parfaite, je veux juste ajouter que pour travailler avec 1 ou 2 décimales (troisième version) :

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

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

3
répondu Leandro Tupone 2014-12-15 19:16:44

Cette question a quelques années, donc je voulais donner une réponse mise à jour.

J'ai utilisé jQuery InputMask et cela fonctionne très bien pour le masquage d'entrée/format (comme les numéros de téléphone, etc.) mais cela ne fonctionne pas vraiment bien pour la monnaie de mon expérience.

Pour la monnaie, je recommande fortementautoNumeric jQuery plugin. Il est bien entretenu et ils ont fondamentalement "pensé à tout" que je pourrais vouloir pour la monnaie.

J'utilise en fait une combinaison des deux parmi ces plugins pour le formatage des numéros de téléphone, les formats de numéros (ISBN, etc), ainsi que des devises (monnaie américaine principalement).

Gardez à l'esprit que jquery.inputmask est principalement sur le contrôle du format d'une valeur, alors que autoNumeric est sur le contrôle spécifique du format de la monnaie.

1
répondu Dan L 2016-06-12 02:54:49

J'utilise l'expression régulière suivante pour la validation des devises:

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

Vous pouvez également autoriser le signe de premier dollar optionnel:

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

Vous pouvez facilement ajouter des tests pour les parenthèses au lieu de signe en ajoutant

\( and \)
0
répondu eitanpo 2011-11-29 13:15:35

Je regardais cela aussi et je suis arrivé à la conclusion qu'il est préférable de construire l'expression rationnelle en fonction de la culture actuelle. Nous pouvons utiliser le

CurrencyPositivePattern 
CurrencyGroupSeparator
CurrencyDecimalSeparator

Propriétés de NumberFormatInfo pour obtenir le format requis.

Edit: quelque chose comme ça

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 : ""); 

Se référer - http://msdn.microsoft.com/en-us/library/hs600312.aspx

0
répondu sidprasher 2012-04-05 10:33:03

J'ai eu du succès avec cela (en prenant des morceaux de certaines des expressions rationnelles ci-dessus). Seule traite jusqu'à des milliers, mais ne devrait pas être trop difficile d'étendre cette

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
répondu JoshMahowald 2012-12-12 17:35:01

Si vous voulez tenir compte d'une erreur humaine, vous pouvez rendre l'expression rationnelle plus indulgente lors de la correspondance de la devise. J'ai utilisé la 2ème belle regex de Keng et l'ai rendue un peu plus robuste pour tenir compte des fautes de frappe.

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

Cela correspondra à l'un de ces chiffres de monnaie appropriés ou mutilés, mais ne ramassera pas l'ordure supplémentaire à la fin après l'espace:

$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
répondu jim 2013-01-05 17:15:13

C'est ce que j'utilise:

Sans leader + ou -

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

Avec, en option, leader + ou -

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

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

0
répondu MIkee 2016-07-07 21:41:50

En utilisant la réponse de Leandro, j'ai ajouté ^(?:[$]|) Au début pour permettre un signe dollar précédent

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

cela correspond à

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

Ne Correspond Pas À

11124.52
234223425.345
234.
.5234
a
a.23
32.a
a.a
z548,452.22
u66.36
0
répondu henrywright88404 2018-06-29 00:49:34