Qual è il “migliore” US RegEx in valuta?

Una rapida ricerca di espressioni regolari di valuta porta un sacco di risultati .

Il problema che ho nella scelta di uno di questi è che l’espressione regolare è difficile da verificare senza testare tutti i casi limite. Potrei passare molto tempo in questo, come sono sicuro che centinaia di altri sviluppatori hanno già fatto.

Qualcuno ha una regex per la valuta degli Stati Uniti che è stata accuratamente testata ?

Il mio unico requisito è che la stringa con corrispondenza sia la valuta statunitense e analizzi System.Decimal :

 [Ws] segno [] [cifre, cifre] [.fractional cifre] [ws] 

 Gli elementi tra parentesi quadre ([e]) sono facoltativi. 
 La seguente tabella descrive ciascun elemento. 

 DESCRIZIONE DELL'ELEMENTO
 ws Spazio bianco opzionale.
 firmare un segno opzionale
 cifre Una sequenza di cifre che va da 0 a 9.
 , Un simbolo separatore specifico per la cultura.
 .  Un simbolo di punto decimale specifico per la cultura.
 cifre frazionarie Una sequenza di cifre che va da 0 a 9. 

ecco alcune cose dai produttori di Regex Buddy. Questi provengono dalla biblioteca, quindi sono fiducioso che siano stati testati a fondo.

Numero: importo in valuta (centesimi obbligatori) Separatori facoltativi di migliaia; frazione obbligatoria a due cifre

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

Numero: importo in valuta (centesimi facoltativi) Separatori facoltativi di migliaia; frazione opzionale a due cifre

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

Numero: importo in valuta USA e UE (centesimi facoltativi) È ansible utilizzare la notazione in stile USA 123.456.78 e la notazione in stile europeo 123.456,78. Separatori facoltativi di migliaia; frazione opzionale a due cifre

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

Ho trovato questa espressione regolare in linea su http://www.RegExLib.com di Kirk Fuller, Gregg Durishan

L’ho usato con successo negli ultimi due anni.

 "^\$?\-?([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}))\)$" 

Non completamente testato (l’ho appena scritto!), Ma sembra comportarsi correttamente:

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

Set di prova:

 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 

Nota: il tuo System.Decimal dipende dalle impostazioni internazionali, difficile da eseguire in espressioni regolari, tranne forse durante la creazione. Ho assunto cifre raggruppate per tre, anche se in alcune culture (locales) ci sono regole diverse.
È banale aggiungere spazi bianchi attorno ad esso.

La risposta di Keng è perfetta, voglio solo aggiungere che per lavorare con 1 o 2 decimali (per la terza versione):

 "^[+-]?[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

Questa domanda ha qualche anno, quindi ho voluto dare una risposta aggiornata.

Ho usato jQuery InputMask e funziona molto bene per il mascheramento di input / formato (come numeri di telefono, ecc.) Ma NON funziona davvero bene per la valuta dalla mia esperienza.

Per valuta, consiglio vivamente il plugin jQuery autoNumeric . È ben tenuto e hanno praticamente “pensato a tutto” che potrei volere per valuta.

In realtà utilizzo una combinazione di entrambi questi plug-in per la formattazione di numeri di telefono, formati numerici (ISBN, ecc.) E valute (principalmente valuta statunitense).

Tieni presente che jquery.inputmask riguarda principalmente il controllo del formato di un valore, mentre autoNumeric riguarda il controllo specifico del formato della valuta.

Sto usando la seguente espressione regolare per la convalida della valuta:

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

Puoi anche consentire il simbolo del dollaro principale opzionale:

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

È ansible aggiungere facilmente test per parentesi invece di firmare aggiungendo

 \( and \) 

Stavo anche osservando questo e sono giunto alla conclusione che è meglio build la regex basata sulla cultura attuale. Possiamo usare il

 CurrencyPositivePattern CurrencyGroupSeparator CurrencyDecimalSeparator 

proprietà di NumberFormatInfo per ottenere il formato richiesto.

Modifica: qualcosa di simile

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

fare riferimento a http://msdn.microsoft.com/en-us/library/hs600312.aspx

Ho avuto successo con questo (prendendo bit e pezzi da alcune delle regex di cui sopra). Gestisce solo fino a migliaia, ma non dovrebbe essere troppo difficile per estenderlo

 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) } 

Nel caso in cui si desideri rendere conto dell’errore umano, è ansible rendere più regolare la regex quando si combina la valuta. Ho usato la seconda regex di Keng e l’ho resa un po ‘più robusta per tenere conto degli errori di battitura.

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

Questo corrisponderà a qualsiasi di queste figure di valuta corrette o mutilate, ma non raccoglierà la spazzatura in eccesso alla fine dopo lo spazio:

 $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 

Questo è quello che uso:

Senza guidare + o –

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

Con opzionale leader + o –

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

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

Usando la risposta di Leandro ho aggiunto ^(?:[$]|) All’inizio per consentire un segno di dollaro precedente

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

Questo corrisponde

 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 

Non corrisponde

 11124.52 234223425.345 234. .5234 a a.23 32.a aa z548,452.22 u66.36