Ruby 中的安全整数解析
我有一个字符串,例如 '123'
,我想将其转换为整数 123
。
我知道你可以简单地执行 some_string.to_i
,但这会将 'lolipops'
转换为 0
,这不是我想要的效果。 当我尝试转换无效的内容时,我希望它在我面前爆炸,并带有一个美好而痛苦的Exception
。 否则,我无法区分有效的 0
和根本不是数字的东西。
编辑:我一直在寻找标准的方法,没有正则表达式的欺骗。
I have a string, say '123'
, and I want to convert it to the integer 123
.
I know you can simply do some_string.to_i
, but that converts 'lolipops'
to 0
, which is not the effect I have in mind. I want it to blow up in my face when I try to convert something invalid, with a nice and painful Exception
. Otherwise, I can't distinguish between a valid 0
and something that just isn't a number at all.
EDIT: I was looking for the standard way of doing it, without regex trickery.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
Ruby 内置了此功能:
正如 Joseph Pecoraro 的回答所述,您可能需要监视有效的非十进制数字的字符串,例如以
0x
开头的十六进制字符串和以0b
开头的二进制字符串,以及以零将被解析为八进制。Ruby 1.9.2 为基数添加了可选的第二个参数,因此可以避免上述问题:
Ruby has this functionality built in:
As noted in answer by Joseph Pecoraro, you might want to watch for strings that are valid non-decimal numbers, such as those starting with
0x
for hex and0b
for binary, and potentially more tricky numbers starting with zero that will be parsed as octal.Ruby 1.9.2 added optional second argument for radix so above issue can be avoided:
这可能有效:
This might work:
另请注意当前接受的解决方案可能对解析十六进制、八进制和二进制数产生的影响:
在以
0x
或0X
开头的 Ruby 数字是十六进制,< code>0b 或0B
是二进制,只有0
是八进制。 如果这不是所需的行为,您可能需要将其与其他一些解决方案结合起来,这些解决方案首先检查字符串是否与模式匹配。 如/\d+/
正则表达式等。Also be aware of the affects that the current accepted solution may have on parsing hex, octal, and binary numbers:
In Ruby numbers that start with
0x
or0X
are hex,0b
or0B
are binary, and just0
are octal. If this is not the desired behavior you may want to combine that with some of the other solutions that check if the string matches a pattern first. Like the/\d+/
regular expressions, etc.已接受解决方案的另一个意外行为(1.8、1.9 都可以):
因此,如果您不确定传入的内容,请确保添加
.to_s
。Another unexpected behavior with the accepted solution (with 1.8, 1.9 is ok):
so if you're not sure what is being passed in, make sure you add a
.to_s
.我喜欢 Myron 的答案,但它患有“我不再使用 Java/C#,所以我永远不会再使用继承”的 Ruby 疾病。 打开任何类都可能充满危险,因此应谨慎使用,尤其当它是 Ruby 核心库的一部分时。 我并不是说永远不要使用它,但它通常很容易避免,并且有更好的选择可用,例如
然后,当您希望使用可能是数字的字符串时,很清楚您在做什么,并且您不这样做不要破坏任何核心类,例如,
您可以在初始化中添加各种其他检查,例如检查二进制数等。但最重要的是,Ruby 是为人服务的,而为人服务意味着清晰。 通过变量名和其类名来命名对象会使事情更加更加清晰。
I like Myron's answer but it suffers from the Ruby disease of "I no longer use Java/C# so I'm never going to use inheritance again". Opening any class can be fraught with danger and should be used sparingly, especially when it's part of Ruby's core library. I'm not saying don't ever use it, but it's usually easy to avoid and that there are better options available, e.g.
Then when you wish to use a string that could be a number it's clear what you're doing and you don't clobber any core class, e.g.
You can add all sorts of other checks in the initialize, like checking for binary numbers etc. The main thing though, is that Ruby is for people and being for people means clarity. Naming an object via its variable name and its class name makes things much clearer.
我必须在上一个项目中处理这个问题,我的实现类似,但有点不同:
I had to deal with this in my last project, and my implementation was similar, but a bit different:
回复:克里斯的回答
你的实现让我们像“1a”或“b2”这样的东西通过。 怎么样:
这个输出:
Re: Chris's answer
Your implementation let's things like "1a" or "b2" through. How about this instead:
This outputs:
可能不是最干净的方法,但应该可行。
Probably not the cleanest way to do it, but should work.