web-dev-qa-db-ja.com

「最高の」米国通貨正規表現とは何ですか?

通貨の正規表現をすばやく検索すると、 多くの結果 が表示されます。

これらのいずれかを選択する際の問題は、すべてのEdgeケースをテストしないと正規表現を検証することが難しいことです。他の何百人もの開発者がすでにやったと確信しているので、私はこれに多くの時間を費やすことができました。

誰もが徹底的にテストされた米国通貨の正規表現を持っていますか?

私の唯一の要件は、一致する文字列がU.S Currencyであり、 System.Decimalに解析 であることです。

 [ws] [sign] [digits、] digits [.fractional-digits] [ws] 
 
角括弧内の要素([および])はオプションです。 
次の表で各要素について説明します。 
 
要素の説明
 wsオプションの空白。
 signオプションの記号。
 digits 0〜9の範囲の数字のシーケンス。 ____。]、カルチャ固有の桁区切り記号。
。カルチャ固有の小数点記号。
小数桁0〜9の範囲の数字のシーケンス。
45
Robert Claypool

regex Buddyのメーカーの製品をいくつか紹介します。これらはライブラリからのものであるため、完全にテストされたと確信しています。

数値:通貨額(セント必須)オプションの千単位の区切り記号。必須の2桁の小数

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

数値:通貨額(オプションでセント)オプションの千単位の区切り記号。オプションの2桁の小数部

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

数値:USおよびEUの通貨金額(セントはオプション)US形式の123,456.78表記およびヨーロッパ形式の123.456,78表記を使用できます。オプションの千単位の区切り記号。オプションの2桁の小数部

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

この正規表現は、Kirk Fuller、Gregg Durishanのwww.RegExLib.comでオンラインで見つけました。

私は過去数年間それをうまく使用しています。

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

完全にはテストされていません(私はそれを書いたばかりです!)が、正しく動作しているようです:

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

テストセット:

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

注:System.Decimalはロケールに依存しており、おそらくビルド時を除き、正規表現で作成するのは困難です。一部の文化(ロケール)で異なる規則がある場合でも、数字は3でグループ化されていると想定しました。
周囲に空白を追加するのは簡単です。

7
PhiLho

Kengの答えは完璧です。1桁または2桁の小数(3番目のバージョン)で作業するために追加したいだけです。

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

この質問は数年前のものなので、最新の回答をしたいと思いました。

jQuery InputMask を使用しました。入力/フォーマットマスキング(電話番号など)には非常にうまく機能しますが、私の経験からすると通貨にはあまりうまくいきません。

通貨については、 autoNumeric jQueryプラグインを強くお勧めします。よく手入れされていて、彼らは基本的に「すべてのことを考えている」ので、私は通貨を求めています。

実際、これらのプラグインの両方を組み合わせて、電話番号、数値形式(ISBNなど)、および通貨(主に米国の通貨)をフォーマットします。

それを念頭に置いて jquery.inputmaskは主に値の形式を制御することに関するものであり、autoNumericは通貨の形式を具体的に制御することに関するものです。

1
Dan L

人的エラーを考慮したい場合は、通貨を照合するときに正規表現をより寛容にすることができます。 Kengの2番目のNice正規表現を使用し、タイプミスを説明するためにもう少し堅牢にしました。

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

これは、これらの適切なまたは破損した通貨の数字のいずれかに一致しますが、スペースの後の最後に余分なジャンクを拾いません:

$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
jim

通貨の検証に次の正規表現を使用しています。

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

オプションの先行ドル記​​号を許可することもできます。

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

以下を追加することで、サインの代わりに括弧のテストを簡単に追加できます

\( and \)
0
eitanpo

私もこれを見ていましたが、現在の文化に基づいて正規表現を構築するのが最善であるという結論に達しました。使用できます

CurrencyPositivePattern 
CurrencyGroupSeparator
CurrencyDecimalSeparator

NumberFormatInfoのプロパティを使用して、必要な形式を取得します。

編集:このようなもの

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
sidprasher

これは私が使用するものです:

先頭の+または-なし

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

オプションの先行+または-

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

ネットフィドル: https://jsfiddle.net/compsult/9of63cwk/12/

0
MIkee

Leandroの答えを使用して、先頭に^(?:[$]|)を追加して、先行するドル記号を許可しました

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

これが一致した

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

一致しなかった

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

私はこれで成功しました(上記の正規表現の一部から少しずつ取ります)。数千までしか処理しませんが、それを拡張するのはそれほど難しくないはずです

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
JoshMahowald