【问题标题】:How to validate that a string is a proper hexadecimal value in Ruby?如何验证字符串是 Ruby 中正确的十六进制值?
【发布时间】:2013-12-22 14:35:51
【问题描述】:

我正在用 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,如果只是数字也可以。

我希望避免意大利面条式代码,其中充斥着“if”语句。我希望有人可以提供“单行”或某种形式的优雅代码。

谢谢!

【问题讨论】:

  • ^$ 锚定你的模式,否则,零匹配,Z 不需要匹配。 true if "0Z" =~ /^[A-Fa-f0-9]+$/
  • @MichaelBerkowski:你应该把它作为答案。

标签: ruby regex hex


【解决方案1】:

String#hex 不会将整个字符串解释为十六进制,它会从字符串的开头提取直到可以解释为十六进制。对于"0Z""0" 是有效的十六进制,因此它解释了该部分。对于"asfd""a" 是有效的十六进制,因此它解释了该部分。

【讨论】:

    【解决方案2】:

    !str[/\H/] 将查找无效的十六进制值。

    【讨论】:

    • 你碰巧知道是否有与此等效的二进制文件吗?
    • 这在 1.8.7 上不起作用,并且不处理带有“0x”的前导字符串。但仍然很酷。
    • @AShelly 没什么大不了的:!str.gsub('0x','')[/\H/]
    【解决方案3】:

    一种方法:

    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" 这样的字符串通过。

    【讨论】:

      【解决方案4】:

      由于 Ruby 内置了十六进制文字,您可以评估字符串并挽救 SyntaxError

      eval "0xA" => 10

      eval "0xZ" => 语法错误

      您可以在类似的方法上使用它

      def is_hex?(str)
        begin
          eval("0x#{str}")
          true
        rescue SyntaxError
          false
        end
      end
      
      is_hex?('0A') => true
      is_hex?('0Z') => false
      

      当然,既然您使用的是 eval,请确保您只向方法发送安全值

      【讨论】:

      • 好主意,但你必须告诉如何根据 OP 提供的字符串来做到这一点。
      • 不知道为什么我得到两个否定,因为我在那里提供了一个完全有效的答案。为了说明我的观点,我将在答案中添加一个方法,看看如何使用它
      • 显然1; "system \"rm -rf /\"; 5" 是一个有效的十六进制数。 :)
      • 好吧,在我刚刚提供的示例方法中,我是说您在进行 eval 时必须小心。这是不言而喻的
      • 这不是一个“坏”的例子,但我希望找到一个开销最小的优雅解决方案。根据我的经验,使用“eval”是最后的手段。
      【解决方案5】:

      这是一个老问题,但我自己也遇到了这个问题。我在我的代码中选择了这个:

      str =~ /^\h+$/

      如果 str 为 nil,它具有返回 nil 的额外好处。

      【讨论】:

        猜你喜欢
        • 2012-07-10
        • 2019-07-27
        • 2012-01-13
        • 2023-01-18
        • 2021-11-27
        • 1970-01-01
        • 1970-01-01
        • 2011-02-08
        • 2011-04-14
        相关资源
        最近更新 更多