Viku
Viku

Reputation: 2973

Regex for hexa decimal combination of string

I need a regex which will test the combination of hexadecimal string. Specifically, the string must have:

Currently I am using var macRegex = new RegExp("^[0-9A-Fa-f]{12}$");. The above regex allow strings like "111111111111" , "000000000000" which i want to avoid . It should allow a string like "944a0c122123"

How can I accomplish this?

Upvotes: 1

Views: 265

Answers (4)

jdphenix
jdphenix

Reputation: 15425

You can use a set of positive lookaheads to do this.

Here's the regex:

/(?!0).(?=.*\d)(?=.*[a-f])[\da-f]{11}/i

(?!0)                                 Negative lookahead
.                                     Match any character
(?=                                   Positive lookahead
    .*                                Match any character zero to unlimited
    \d                                Match a digit
)
(?=                                   Positive lookahead
    .*                                Match any character zero to unlimited
    [a-f]                             Match a character a-f
)
[\da-f]{11}                           Match any of the valid characters, 12 times

You can conceptualize this is a logical AND of the expressions in each lookahead (except for the .*).

var regexp = /(?!0).(?=.*\d)(?=.*[a-f])[\da-f]{11}/i;
var test1 = "000000000000";
var test2 = "111111111111";
var test3 = "8179acf0871a";
var test4 = "9abzzzzzzzzz";
var test5 = "0179acf0871a";

console.log(regexp.test(test1));
console.log(regexp.test(test2));
console.log(regexp.test(test3));
console.log(regexp.test(test4));
console.log(regexp.test(test5));

Here's a snippet that demonstrates similar input samples.

Upvotes: 1

Toto
Toto

Reputation: 91385

Here is the way I'd go:

/^(?=.*\d)(?=.*[a-f])[1-9a-f][\da-f]{10}[1-9a-f]$/i

Explanation:

/
  ^             : begining of string
  (?=.*\d)      : lookahead, at least one digit
  (?=.*[a-f])   : lookahead, at least one letter in range a-f
  [1-9a-f]      : first character, not zero
  [\da-f]{10}   : ten hex character
  [1-9a-f]      : last character, not zero
  $             : end of string
/i              : case insensitive

Upvotes: 2

RobG
RobG

Reputation: 147383

To keep the regular expression simple, I'd separate matching the pattern and checking the length:

var re = /^(\d+[a-f]+[\da-f]*|[a-f]+\d+[\da-f]*)$/i;
var s  = '011001aFFA77';
console.log(re.test(s) && s.length == 12); // true

var s  = '000000000000';
console.log(re.test(s) && s.length == 12); // false

The pattern to match:

  1. one or more digits followed by one or more letters a to f followed by zero or more digits or letters a to f, OR
  2. one or more letters a to f followed by one or more digits followed by zero or more digits or letters a to f

then check the length is 12.

Edit

To meet the new criterion "can't start with 0" (and simplify the expression a bit), the regular expression can be:

var re = /^([1-9]\d*[a-f]+|[a-f]+\d+)[\da-f]*$/i;

var s  = '011001aFFA77';
console.log(re.test(s) && s.length == 12); // false

var s  = '000000000000';
console.log(re.test(s) && s.length == 12); // false


var s  = '011001aFFA77';
console.log(re.test(s) && s.length == 12); // false

var s  = 'a11001aFFA77';
console.log(re.test(s) && s.length == 12); // true

var s  = '311001aFFA77';
console.log(re.test(s) && s.length == 12); // true

var s = '0000000000a1';
console.log(re.test(s) && s.length == 12); // false

Upvotes: 3

Bob
Bob

Reputation: 523

If you don't mind a non RegExp solution this function should do what you want.

function only_hex_len_12(str){

    // if the string is the wrong length return false
    if(str.length!=12) return false;

    var hex_val=parseInt(str,16);
    var dec_val=parseInt(str,10);


    // If the string is dec return false
    if(!isNaN(dec_val)) return false;


    // If the string is not hex return false
    if(isNaN(hex_val)) return false;

    // Otherwise the string is okay so return true
    return true;
}

If you want a RegExp solution RobG's answer looks good.

Upvotes: 2

Related Questions