我正在用Ruby编写6502汇编程序。我正在寻找一种以字符串形式验证十六进制操作数的方法。我知道String对象提供了一个“十六进制”方法来返回一个数字,但这是我遇到的一个问题:
"0A".hex #=> 10 - a valid hexadecimal value
"0Z".hex #=> 0 - invalid, produces a zero
"asfd".hex #=> 10 - Why 10? I guess it reads 'a' first and stops at 's'?
通过输入一堆胡言乱语,你会得到一些奇怪的结果。我需要的是首先验证该值是否为合法的十六进制字符串的方法。
我正在玩正则表达式,并意识到我可以这样做:
true if "0A" =~ /[A-Fa-f0-9]/
#=> true
true if "0Z" =~ /[A-Fa-f0-9]/
#=> true <-- PROBLEM
我不确定如何解决这个问题。我需要能够验证字母只是A-F,如果它只是数字也可以。
我希望避免意大利面条代码,充斥着“如果”的陈述。我希望有人可以提供“单行”或某种形式的优雅代码。
谢谢!
答案 0 :(得分:7)
!str[/\H/]
会查找无效的十六进制值。
答案 1 :(得分:3)
String#hex
不会将整个字符串解释为十六进制,它从字符串的开头提取,直到它可以被解释为十六进制。对于"0Z"
,"0"
是有效的十六进制,因此它解释了该部分。对于"asfd"
,"a"
是有效的十六进制,因此它解释了该部分。
答案 2 :(得分:1)
一种方法:
str.to_i(16).to_s(16) == str.downcase
另:
str =~ /\A[a-f0-9]+\Z/i # or simply /\A\h+\Z/ (see hirolau's answer)
关于你的正则表达式,你必须使用锚点(\A
作为字符串的开头,\Z
作为字符串的结尾)来表示你想要完整的字符串匹配。此外,+
会重复匹配一个或多个字符。
请注意,您可以使用^
(行首)和$
(行尾),但这样可以传递"something\n0A"
等字符串。
答案 3 :(得分:0)
这是一个古老的问题,但是我自己才遇到这个问题。我在代码中选择了此选项:
str =~ /^\h+$/
如果str为nil,则具有返回nil的额外好处。
答案 4 :(得分:-2)
由于Ruby内置了文字十六进制,因此您可以评估该字符串并解除SyntaxError
eval“0xA”=&gt; 10
eval“0xZ”=&gt;的SyntaxError
您可以在类似
的方法上使用此功能def is_hex?(str)
begin
eval("0x#{str}")
true
rescue SyntaxError
false
end
end
is_hex?('0A') => true
is_hex?('0Z') => false
当然,因为您使用的是eval,所以请确保您只向方法发送安全值