科学表記で数値を文字列として受け取り、係数と指数を別々の項目として分割する関数を記述できるようにしたいと考えています。正規表現を使用することもできますが、着信番号が正規化されていない可能性があるため、正規化してパーツを分割できるようにしたいと考えています。
同僚はVB6を使用したソリューションの一部を手にしましたが、以下の筆記録が示すように、それは完全にはありません。
cliVe> a = 1e6
cliVe> ? "coeff: " & o.spt(a) & " exponent: " & o.ept(a)
coeff: 10 exponent: 5
1と6である必要があります
cliVe> a = 1.1e6
cliVe> ? "coeff: " & o.spt(a) & " exponent: " & o.ept(a)
coeff: 1.1 exponent: 6
正しい
cliVe> a = 123345.6e-7
cliVe> ? "coeff: " & o.spt(a) & " exponent: " & o.ept(a)
coeff: 1.233456 exponent: -2
正しい
cliVe> a = -123345.6e-7
cliVe> ? "coeff: " & o.spt(a) & " exponent: " & o.ept(a)
coeff: 1.233456 exponent: -2
-1.233456および-2である必要があります
cliVe> a = -123345.6e+7
cliVe> ? "coeff: " & o.spt(a) & " exponent: " & o.ept(a)
coeff: 1.233456 exponent: 12
正しい
何か案は?ちなみに、CliveはVBScriptに基づくCLIであり、私の weblog にあります。
Google on "scientific notation regexp" は、 this one (do n't use it !!!!)を使用します
*** warning: questionable ***
/[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?/
これには、-。5e7や+ 00000e33などのケースが含まれます(どちらも許可したくない場合があります)。
代わりに、highlyDoug Crockfordの JSON Webサイト の構文を使用して、JSONで数値を構成するものを明示的に文書化することをお勧めします。これは、そのページから取得した対応する構文図です。
(ソース: json.org )
彼の json2.js スクリプト(JavaScriptでのJSONとの安全な変換)の456行目を見ると、正規表現のこの部分が表示されます。
/-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/
皮肉なことに、これは彼の構文図と一致しません....(バグを報告する必要があるように見えます)その構文図を実装する正規表現は次のとおりです。
/-?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?/
最初の+も許可したい場合は、次のようになります。
/[+\-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?/
キャプチャー括弧を好みに追加します。
また、次のように、含めたい(または含めない)可能性を確実に含めるために、一連のテストケースを具体化することを強くお勧めします。
allowed:
+3
3.2e23
-4.70e+9
-.2E-4
-7.6603
not allowed:
+0003 (leading zeros)
37.e88 (dot before the e)
幸運を!
最高評価の回答を基に、正規表現を/^[+\-]?(?=.)(?:0|[1-9]\d*)?(?:\.\d*)?(?:\d[eE][+\-]?\d+)?$/
になるように少し修正しました。
これが提供する利点は次のとおりです。
.9
_(_(?:0|[1-9]\d*)
_を使用して_?
_をオプションにした)のような一致する数値を許可(?=.)
_を使用)e9
_が必要であるため、_\d
_の一致を防止しますこれの私の目標は、重要な数値を取得し、重要な計算を行うためにそれを使用することです。そのため、/^[+\-]?(?=.)(0|[1-9]\d*)?(\.\d*)?(?:(\d)[eE][+\-]?\d+)?$/
のように、グループをキャプチャしてスライスします。
これから重要な数値を取得する方法の説明:
parseFloat()
に渡すことができる数ですundefined
を_''
_で置き換える)と、有効数字を抽出できる元の数が得られます。この正規表現は、JavaScriptが受け入れることもあるが問題を引き起こし、重要な数値に何も追加しない左パディングゼロの照合も防止します。そのため、左パディングゼロの防止は利点として(特にフォームでは)わかります。ただし、正規表現を変更して、左側に埋め込まれたゼロを混乱させることができると私は確信しています。
この正規表現で見られるもう1つの問題は、_90.e9
_または他のそのような数値と一致しないことです。ただし、このような数字を避けるのは科学表記法の慣例であるため、これまたは類似の一致はほとんどありません。 JavaScriptで入力することもできますが、_9.0e10
_と同じくらい簡単に入力して、同じ有意な数値を得ることができます。
[〜#〜]更新[〜#〜]
テストでは、_'.'
_と一致する可能性があるというエラーも検出しました。したがって、先読みを_(?=\.\d|\d)
_に変更して、最終的な正規表現を作成する必要があります。
_/^[+\-]?(?=\.\d|\d)(?:0|[1-9]\d*)?(?:\.\d*)?(?:\d[eE][+\-]?\d+)?$/
_
これが私がすぐにハッキングしたPerlコードです。
my($sign,$coeffl,$coeffr,$exp) = $str =~ /^\s*([-+])?(\d+)(\.\d*)?e([-+]?\d+)\s*$/;
my $shift = length $coeffl;
$shift = 0 if $shift == 1;
my $coeff =
substr( $coeffl, 0, 1 );
if( $shift || $coeffr ){
$coeff .=
'.'.
substr( $coeffl, 1 );
}
$coeff .= substr( $coeffr, 1 ) if $coeffr;
$coeff = $sign . $coeff if $sign;
$exp += $shift;
say "coeff: $coeff exponent: $exp";