我想能够写一个函数,它接收一个用科学符号表示的数字作为一个字符串,并把系数和指数分开作为单独的项。我可以使用一个正则表达式,但是输入的数字可能不是标准化的,我更希望能够标准化,然后将部分分解。
一位同事已经找到了使用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,可以在myweblog上找到。
Google在"scientific notation regexp"上显示了许多匹配项,包括this one(不要使用它!!!!)使用
其中包括-.5e7和+00000e33(这两种情况您可能都不允许)。
相反,我强烈建议您使用Doug Crockford的JSON website语法,它显式地记录了JSON中数字的构成。下面是从该页获取的相应语法图:
(来源:json.org)
如果您查看他的json2.js脚本的第456行(在javascript中安全地转换为JSON或从JSON转换为JSON),您将看到regexp的这一部分:
讽刺的是,这和他的语法图不匹配。。。。(看起来我应该提交一个bug)我相信实现该语法图的regexp是这样的:
如果你也想要一个初始的+值,你会得到:
根据您的喜好添加捕获括号。
我还强烈建议您充实一堆测试用例,以确保您包括那些您希望包括(或不包括)的可能性,例如:
祝你好运!
基于最高级别的答案,我稍微修改了regex为
/^[+\-]?(?=.)(?:0|[1-9]\d*)?(?:\.\d*)?(?:\d[eE][+\-]?\d+)?$/
。这样做的好处是:
.9
这样的匹配数字(我用?
使(?:0|[1-9]\d*)
可选)(?=.)
)e9
,因为它需要在科学符号之前使用\d
我的目标是用它来捕捉有意义的数字和做有意义的数学。因此,我还将用So:
/^[+\-]?(?=.)(0|[1-9]\d*)?(\.\d*)?(?:(\d)[eE][+\-]?\d+)?$/
这样的捕获组来分割它。如何从中获取有效数字的说明:
parseFloat()
的数字undefined
替换为''
)应给出可从中提取有效数字的原始数字。这个regex还防止匹配左填充的零,JavaScript有时接受左填充的零,但我已经看到这会导致问题,并且不会给有效数字添加任何内容,所以我认为防止左填充的零是一个好处(特别是在表单中)。不过,我相信regex可以被修改为吞噬左填充的零。
我发现这个regex的另一个问题是它与
90.e9
或其他类似的数字不匹配。然而,我发现这种或类似的匹配是极不可能的,因为这是科学记数法中的惯例,以避免这样的数字。尽管可以用JavaScript输入,但也可以轻松地输入9.0e10
,并获得相同的有效数字。更新
在我的测试中,我还发现了它可能匹配
'.'
的错误。因此,应该将look ahead修改为(?=\.\d|\d)
,这将导致最终的regex:这里有一些Perl代码,我刚刚很快就破解了。
相关问题 更多 >
编程相关推荐