Regex matching for hexadecimals

Viewed 419

I'm working on a project (website) where I would like to validate various forms of Binary numbers. The first of which that I'd like to tackle is some Regex expression that handles the various 'valid' ways of representing hexadecimal digits. They are:

  1. Leading '0x'
  2. Leading'$'
  3. Trailing 'h'

I'm just not sure how to handle this in Regex, as you can obviously only have ONE of the three options present at any one time:

This is the query that I've currently got:(0x)?)[0-9A-Fa-f]

  • Works for the case of leading 0x
  • (Obviously) doesn't detect leading $ or trailing h
  • Not sure how to implement the 'only oone' functionality.

~~ Valid ~~

0xA, 0xa, 0x101, 0x747, 101h, $747

~~ Invalid ~~

A (just hexadecimal digit by itself), 0xa$ (Leading 0x and trailing h), $0xA (Leading $ and 0x)

Thanks :)

2 Answers

The simplest approach would be defining all three forms as alternative

/^((0x[0-9a-f]+)|(\$[0-9a-f]+)|([0-9a-f]+h))$/i

You can also combine the first to forms with different prefixes into one

/^(((0x|\$)[a-f0-9]+)|([a-f0-9]+h))$/i

Since you didn't specify a particular language, I used javascript syntax, but in principle it's the same in other languages

  • / denotes the beginning and the end of the regexp in JS, ie it does not belong to the regualar expression itself.

  • i is an regex flag, to make the matching case insensitive, ie it matches 0xA, 0Xa, aH and Ah. If you don't want to match 0X prefix or H suffix, you must remove the i flag and explicitely add A-F to the regex number portion

  • ^ and $ are the beginning and the end of the string. Thus it does only match a complete string and not when a regex is part of a bigger string. Ie it matches "0xffff" but not "foo 0xffff bar"

  • ((0x|\$)[a-f0-9]+) matches a valid hexadecimal number prefixed by either 0x or $. As $ is a special character in regular expressions, it must be escaped with \ to be matched literally.

  • ([a-f0-9]+h) matches a valid hexadecimal number followed by exactly one h

You can use an alternation with 2 alternatives, and if you don't need to refer to the capture groups afterwards you can use a non capture group (?:

^(?:(?:0x|\$)[0-9A-Fa-f]+|[0-9A-Fa-f]+h)$
  • ^ Start of string
  • (?: Non capture group
    • (?:0x|\$)[0-9A-Fa-f]+ Match eiter 0x or $ and 1+ times any of the listed ranges
    • | Or
    • [0-9A-Fa-f]+h Match 1+ times any of the listed ranges followed by h
  • ) Close non capture group
  • $ End of string

Regex demo


You can not validate the whole pattern while typing, you have to validate the whole pattern while submitting / confirming.

What you might do is narrow down the possible options while typing like for example and at the end validate the whole pattern.

^(?:(?:0x?|\$)[a-f0-9]*|[a-f0-9]+h?)?

Regex demo

Related