1

I'm trying to build a check that reliably evaluates whether the input ($f_username) is a MAC Address via Regex 'cause there are different Syntax it could take. Upon finding a match. this should be transferred to lowercase without deliminators.

The function works fine in matching and transforming most input, but will wrongly match longer input... e.g. 11-22-33-44-55-66-77-88 would be transferred to 11-22-33-44-55-66 and $match is set to true...

This should cause the function to go to the "else branch" as is is not an exact match of the pattern... however it contains a match... does anybody have an idea how to properly match this ?

Thanks for taking the time to read this and thanks in advance for any answers :)

function username_check($f_username) {
  global $match;
  if (preg_match_all("/([0-9a-fA-F]{2})[^0-9a-fA-F]?([0-9a-fA-F]{2})[^0-9a-fA-F]?([0-9a-fA-F]{2})[^0-9a-fA-F]?([0-9a-fA-F]{2})[^0-9a-fA-F]?([0-9a-fA-F]{2})[^0-9a-fA-F]?([0-9a-fA-F]{2})/", $f_username, $output, PREG_PATTERN_ORDER)) {
    for ($i = 1; $i <= 6; $i++) {
      $new_username .= strtolower($output[$i][0]);
    }
    $match = true;
    $new_username = "'" . $new_username . "'"; //for later use in SQL-Query
  } else {
    $match = false;
  }
  return $new_username;
}
Suman Barick
  • 3,311
  • 2
  • 19
  • 31
Felix Joel
  • 75
  • 1
  • 8
  • Instead of using a long, complex and hard to maintain regex pattern, have you considered to use multiple smaller regular expressions and evaluate against each one of them in turn? – Matiss Jul 14 '15 at 15:53
  • I have, but ultimately I feel making the Regex as encompassing as possible is the way to go. Basically the regex I'm employing is easy: ([0-9a-fA-F]{2}) = find exactly 2 hex digits [^0-9a-fA-F]? = find one or none deliminator (That isn't hex) Any MAC is built that way, 6 hex pairs and 5 or no deliminators. – Felix Joel Jul 14 '15 at 15:55
  • 1
    Look here: http://stackoverflow.com/questions/4260467/what-is-a-regular-expression-for-a-mac-address – Ondřej Šotek Jul 14 '15 at 15:56
  • `(?:(?:[A-Fa-f0-9]{2}-){5}[A-Fa-f0-9]{2})` for `xx-xx-xx-xx-xx-xx` style mac addresses – Filip Haglund Jul 14 '15 at 16:04
  • Yes, that is nice, but I have to use a generic form as the input will contain different Syntaxes (11.22.33.44.55.66, 11-22-33-44-55-66, 11:22:33:44:55:66:77, 1122.3344.5566). I've played around with regex a lot to find one that does them all.. The problem is not one of recognising a pattern, but that the limits are not kept. – Felix Joel Jul 14 '15 at 17:12

1 Answers1

1

I recommend using the RegEx from this answer, as it ensures a well-formed MAC-address. If you want to add spaces to the list of delimiters, just replace this [-:] with this [: -].

You are experiencing the problem you described because you haven't bound your RegEx to the start, or the end of a string. Which means that as long as there's a match somewhere inside the string it's a valid match.
To bind it to the start of a string, use ^ just after the opening delimiter. To bind it at the end of a string, I recommend* using \z just before the closing delimiter.

* Reason I recommend \z over $, in PHP, is because the latter will allow a newline after the match. That means that the string "testing\n" will match a pattern bound with $, but not one bound with \z. Most of the times you really do not want that newline.

Community
  • 1
  • 1
ChristianF
  • 2,068
  • 9
  • 14