Skip to content
Advertisement

Regex match a mac address without semi-columns

I am trying to understand why the below function is returning weird results

<?
$string = "001122334 001122334455 0011 0011223344556677";
preg_match_all('/([a-fA-F0-9]){12}/', $str, $matches);
?>

I don’t get why the 001122334455 appears twice and why is the 5 5 doing there. I am looking to find MAC Address without semi-columngs match

Output

Array
( 
[0] => Array
    (
        [0] => 001122334455
        [1] => 001122334455
    )

[1] => Array
    (
        [0] => 5
        [1] => 5
    )
)

Advertisement

Answer

Your regex

  • contains a repeated capturing group, ([a-fA-F0-9]){12}, that is, a hex char is captured into a group, and then the value of the group is re-written 11 times more (all in all, 12 times), so the last hex char captured lands in the second matches subarray (in each match you get with your input string, it is 5, thus, you have two 5s in your second array).
  • is not anchored on both sides, so it is found anywhere inside the string, so you get two matches, 001122334455 is matched and 001122334455 in 0011223344556677 is also matched.

Remove the capturing parentheses and use a whole word matching pattern like

# Word boundaries
preg_match_all('/b[a-fA-F0-9]{12}b/', $str, $matches)            
# Whitespace boundaries
preg_match_all('/(?<!S)[a-fA-F0-9]{12}(?!S)/', $str, $matches)   
# Hex char boundaries
preg_match_all('/(?<![a-fA-F0-9])[a-fA-F0-9]{12}(?![a-fA-F0-9])/', $str, $matches) 

See the PHP demo

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement