rubyguides

String#hex

Signature

str.hexInteger

No parameters. Parses the leading hexadecimal digit sequence from str and returns it as an Integer.

what it does

String#hex scans the string one character at a time for a sequence of hexadecimal characters (0–9, a–f, A–F). It accepts an optional sign (+ or -) at the start and an optional 0x prefix (case-insensitive). Parsing stops at the first non-hex character it encounters. Everything after that first non-hex character is ignored.

This makes it useful for reading hex values from config files, parsing hex color codes, and interpreting hex-encoded data from hardware registers or network packets.

It is a practical choice when the input may contain extra text after the number, because parsing stops as soon as the hex sequence ends. That keeps the method forgiving in situations where the numeric part appears at the front and the rest of the string is just annotation or trailing data.

Return Values

ConditionReturn value
Leading hex digits foundInteger (base 16)
No leading hex digits0
Empty string0
With 0x/0X prefixInteger (prefix is ignored)
With sign (+/-)Signed integer

Examples

Basic conversion

"ff".hex          # => 255
"0xff".hex        # => 255
"-0xff".hex       # => -255
"aB".hex          # => 171
"0xDEAD".hex      # => 57005

The 0x prefix is optional. Both "ff" and "0xff" produce the same result.

The method is strict about the front of the string, but it is relaxed about everything after the numeric prefix. That behavior is handy when you want a fast parse of a text value without writing your own scanner.

Parsing stops at non-hex characters

"10xyz".hex       # => 16
"0xFFG".hex       # => 255

The moment a character that isn’t a valid hex digit appears, parsing stops. The G in "0xFFG" is simply ignored.

That stopping point can be helpful in files or payloads where the number is followed by labels, separators, or other metadata. The method keeps the useful prefix and quietly ignores the rest.

Hex Color to RGB

A common use case is extracting RGB channels from a hex color code:

def hex_to_rgb(hex_str)
  hex_str.delete('#').hex
end

hex_to_rgb("#ff5733")  # => 16735475

The example shows how hex can sit at the end of a tiny helper and still do the heavy lifting. Strip the prefix, convert the hex value, and let the caller decide whether to split the integer into channels later.

Extract individual channels by bit-shifting:

def hex_to_channels(hex_str)
  hex = hex_str.delete('#').hex
  r = (hex >> 16) & 0xff
  g = (hex >> 8)  & 0xff
  b =  hex        & 0xff
  [r, g, b]
end

hex_to_channels("#ff5733")  # => [255, 87, 51]

This is a common pattern when a single integer representation is convenient for storage, but separate channels are easier to work with in the next step. The helper keeps the conversion self-contained, which makes the channel extraction logic easier to reuse.

String#hex vs Integer()

Unlike Integer(), String#hex never raises an exception — if no leading hex is found, it silently returns 0:

Integer("0x10")   # => 16
"0x10".hex        # => 16

Integer("xyz")    # => ArgumentError
"xyz".hex         # => 0

Use Integer() when you want strict parsing and an exception on bad input. Use String#hex when you want to silently skip over non-numeric strings.

That difference in error handling is the main decision point. Integer() is better when invalid input should fail loudly, while hex is better when a best-effort conversion is enough.

See Also

  • String#to_i — parse a string as an integer in a specific base (decimal by default)
  • String#delete — remove characters like # from a string before calling hex
  • String#unpack — decode binary data with template formats, including hex decoding via the H* directive