Jump to content

RegEx builder algorithm for MAC address list


spudw2k
 Share

Go to solution Solved by jchd,

Recommended Posts

I've got a tricky one here.  So I have a sorted list of MAC addresses.  I want to write an algorithm that will produce a regular expression that will match each unique MAC address.  

 

For example:

list
12-34-56-34-14-91
12-34-56-80-04-54
12-34-56-80-93-11
12-34-56-EA-76-0F
12-34-56-EA-76-9F
12-34-56-EA-78-11

would yield
12-34-56-(34-14-91|80-(04-54|93-11)|EA-(76-(0F|9F)|78-11))

Demo: https://www.regextester.com/?fam=112582

 

I have some ideas, but I wanted to field this to the forum in case anyone has better ideas or approaches.  

Link to comment
Share on other sites

20 minutes ago, spudw2k said:

I want to write an algorithm that will produce a regular expression that will match each unique MAC address.

If you are planning to write an algorithm for generating regular expressions for matching unique strings in a given set, you can just concatenate all strings with the | meta character which acts as a logical or in your regex.

EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time)

DcodingTheWeb Forum - Follow for updates and Join for discussion

Link to comment
Share on other sites

Purely pseudo stream of thought, but i think this path may eventually get there

#include<array.au3>

$str = '12-34-56-34-14-91' & @CR & _
'12-34-56-80-04-54' & @CR & _
'12-34-56-80-93-11' & @CR & _
'12-34-56-EA-76-0F' & @CR & _
'12-34-56-EA-76-9F' & @CR & _
'12-34-56-EA-78-11'

local $aSplit[0][6] , $sOut

_ArrayAdd($aSplit , $str , 0 , "-" , @CR)

For $i = 0 to 5

   $sOut &= "(" &  _ArrayToString(_ArrayUnique($aSplit , $i , 0 , 0 , 0) , "|") & ")-"

Next

msgbox(0, '' , stringtrimright($sOut , 1))

 

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

Here my try:

#include <array.au3>

Global $sMAC =  '12-34-56-34-14-91' & @CR & _
                '12-34-56-80-04-54' & @CR & _
                '12-34-56-80-93-11' & @CR & _
                '12-34-56-EA-76-0F' & @CR & _
                '12-34-56-EA-76-9F' & @CR & _
                '12-34-56-EA-78-11'

Global $aMACs = StringRegExp($sMAC, "\b[[:xdigit:]-]+\b", 3)

Global $aMACs_splitted[UBound($aMACs)][6], $x, $xx, $y
For $y = 0 To UBound($aMACs) - 1
    $aTmp = StringSplit($aMACs[$y], "-", 3)
    For $x = 0 To UBound($aTmp) - 1
        $aMACs_splitted[$y][$x] = $aTmp[$x]
    Next
Next
Global $sRegEx
For $x = 0 To UBound($aMACs_splitted, 2) - 1
    Dim $aTmp[UBound($aMACs_splitted)]
    For $y = 0 To UBound($aMACs_splitted) - 1
        $aTmp[$y] = $aMACs_splitted[$y][$x]
    Next
    $aTmp = _ArrayUnique($aTmp)
    If $aTmp[0] = 1 Then
        $sRegEx &= $aTmp[1]
    Else
        $sRegEx &= "("
        For $xx = 1 To $aTmp[0]
            $sRegEx &= $aTmp[$xx] & "|"
        Next
        $sRegEx = StringTrimRight($sRegEx, 1) & ")"
    EndIf
    $sRegEx &= "-"
Next
$sRegEx = StringTrimRight($sRegEx, 1)
ConsoleWrite("RegEx pattern: " & $sRegEx & @CRLF)

 

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

@UEZ that produces a pattern which matches entries not in the input table, like 12-34-56-34-04-11

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

1 hour ago, jchd said:

@UEZ that produces a pattern which matches entries not in the input table, like 12-34-56-34-04-11

Yep, the idea doesn't work this way. Thanks for hint!

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

The expected result has an intrisic recursive nature, so the natural code structure shall be (head-first) recursive.

I'll try to write something.

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

9 minutes ago, jchd said:

The expected result has an intrisic recursive nature, so the natural code structure shall be (head-first) recursive.

I'll try to write something.

Yes, I'm just googling for something like "stop if first expression is false"

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Seems to be working, at least with the provided string :

#include <array.au3>

$str = _
  '12-34-56-34-14-91' & @CR & _
  '12-34-56-80-04-54' & @CR & _
  '12-34-56-80-93-11' & @CR & _
  '12-34-56-EA-76-0F' & @CR & _
  '12-34-56-EA-76-9F' & @CR & _
  '12-34-56-EA-78-11'

Global $aSplit[0][6]
_ArrayAdd($aSplit , $str , 0 , "-" , @CR)
Global Const $iMaxRow = Ubound($aSplit,1)-1,$iMaxCol = Ubound($aSplit,2)-1
Global $count = 0, $sRegExp = "", $iLevel = 0

Solution (0,0,0, $iMaxRow,$iMaxCol)
MsgBox ($MB_SYSTEMMODAL,"",StringTrimRight ($sRegExp,1))

Func Solution ($lvl,$sr, $sc, $er, $ec)
  $v = Same ($sr,$sc,$er)
  If $sr <> $er and $v <> $er and $lvl = 1 Then
    $sRegExp &= "("
    $iLevel += 1
  EndIf
  $sRegExp &= $aSplit[$sr][$sc]
  if $sc < $ec Then
    $sRegExp &= "-"
    Solution (1,$sr, $sc+1, $v, $ec)
  EndIf
  if $v < $er then
    $sRegExp &= "|"
    Solution (2,$v+1, $sc, $er, $ec)
    $sRegExp &= ")"
  EndIf
EndFunc

Func Same ($sr, $c, $er)
  For $r = $sr+1 to $er
    If $aSplit[$r][$c] <> $aSplit[$sr][$c] Then Return $r-1
  Next
  Return $er
EndFunc

 

Link to comment
Share on other sites

9 minutes ago, Nine said:

Seems to be working, at least with the provided string :

What is this magic!? :o He's a wizard, Harry

All my code provided is Public Domain... but it may not work. ;) Use it, change it, break it, whatever you want.

Spoiler

My Humble Contributions:
Personal Function Documentation - A personal HelpFile for your functions
Acro.au3 UDF - Automating Acrobat Pro
ToDo Finder - Find #ToDo: lines in your scripts
UI-SimpleWrappers UDF - Use UI Automation more Simply-er
KeePass UDF - Automate KeePass, a password manager
InputBoxes - Simple Input boxes for various variable types

Link to comment
Share on other sites

That gives under par result in case of more varied input.

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

I broke it... duplicate any address :(

Edit: Sorry, it does say unique. I missed that.

Edited by seadoggie01

All my code provided is Public Domain... but it may not work. ;) Use it, change it, break it, whatever you want.

Spoiler

My Humble Contributions:
Personal Function Documentation - A personal HelpFile for your functions
Acro.au3 UDF - Automating Acrobat Pro
ToDo Finder - Find #ToDo: lines in your scripts
UI-SimpleWrappers UDF - Use UI Automation more Simply-er
KeePass UDF - Automate KeePass, a password manager
InputBoxes - Simple Input boxes for various variable types

Link to comment
Share on other sites

Input is supposed to be a sorted array of distinct strings of equal length.

Edited by jchd

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

turns out mine worked fine for the example

#include<array.au3>

$str = '12-34-56-34-14-91' & @CR & _
'12-34-56-80-04-54' & @CR & _
'12-34-56-80-93-11' & @CR & _
'12-34-56-EA-76-0F' & @CR & _
'12-34-56-EA-76-9F' & @CR & _
'12-34-56-EA-78-11'

local $aSplit[0][6] , $sOut

_ArrayAdd($aSplit , $str , 0 , "-" , @CR)

For $i = 0 to 5

   $sOut &= "(" &  _ArrayToString(_ArrayUnique($aSplit , $i , 0 , 0 , 0) , "|") & ")-"

Next


; testing the regexp against the original set, with a rogue entry added

$a = stringsplit($str , @CR , 2)
_ArrayDisplay($a)
_ArrayAdd($a , "12-34-56-EA-79-11")



for $i = 0 to ubound($a) - 1
    msgbox(0, '' , stringregexp($a[$i] , stringtrimright($sOut , 1)))
next

 

Edited by iamtheky

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

2 hours ago, Nine said:

Seems to be working, at least with the provided string

Impressive!  I'll have to digest the code.  Nice work

Agreed, it works well with the provided string.  When I added a MAC to the list it ended up with unbalanced parenthesis.

$str = _
  '12-34-56-34-14-91' & @CR & _
  '12-34-56-80-04-54' & @CR & _
  '12-34-56-80-93-11' & @CR & _
  '12-34-56-EA-76-0F' & @CR & _
  '12-34-56-EA-76-9F' & @CR & _
  '12-34-56-EA-78-11' & @CR & _
  '12-34-56-F1-00-22'

 

Link to comment
Share on other sites

1 hour ago, iamtheky said:

turns out mine worked fine for the example

I like the approach.  It looks simple, but I don't think it is matching only the MAC list, but combinations of MAC bytes.

Link to comment
Share on other sites

Appreciate everyone's brain power and effort on this one.  Fun challenge for me and hopefully ya'll too.

Seen some neat ideas to consider.  @Nine's is closest so far to what I was trying to accomplish.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...