Using regex in Mikrotik and creating search functions with return values
Posted: Tue Mar 12, 2019 3:28 pm
Mikrotik can search by regular expressions, returning a boolean value.
This link https://wiki.mikrotik.com/wiki/Manual:R ... xpressions provides information about the search capabilities for regular expressions. As always, this information is extremely brief.
It is often necessary to get exactly the substring found. Below I offer a script written by me that returns not only the found substring itself, but also the position of its beginning and end.
use:
1. save the above script called ScriptFindPosix
2. in your script:
I will give more examples of use:
This link https://wiki.mikrotik.com/wiki/Manual:R ... xpressions provides information about the search capabilities for regular expressions. As always, this information is extremely brief.
It is often necessary to get exactly the substring found. Below I offer a script written by me that returns not only the found substring itself, but also the position of its beginning and end.
Code: Select all
#use: [$findPosix String Regex startPosition]
#return array: {FoundSubString ; FoundPositionStart; FoundPositionEnd}
:global findPosix do={
:local string [:tostr $1];
:local posix $2;
:local posix0 $posix;
:local fstart [:tonum $3];
:local fend 0;
:if ($fstart < 0) do={ :set fstart 0 };
:local substr [:pick $string $fstart [:len $string]];
:if ([:len $string] > 0 && [:len $posix] > 0 && $fstart <[:len $string] && ($substr ~ $posix)) do={
:while ($fstart < [:len $string]) do={
:set posix $posix0;
:if ([:pick $posix 0] != "^") do={
:set posix ("^".$posix);
:local continue true;
:while ($continue && $fstart < [:len $string]) do={
:if ([:pick $string $fstart [:len $string]] ~ $posix) do={
:set continue false;
} else={:set fstart ($fstart + 1);};
}
}
:if ($fstart < [:len $string]) do={
:if ([:pick $posix ([:len $posix] -1)] != "\$") do={
:set posix ($posix."\$");
:local continue true;
:set fend [:len $string];
:while ($fend > $fstart && $continue) do={
:if ([:pick $string $fstart $fend] ~ $posix) do={:set continue false} else={:set fend ($fend - 1)};
}
} else={:set fend [:len $string];}
}
:if ($fend > $fstart) do={:return {[:pick $string $fstart $fend] ; $fstart ;$fend};};
:set fstart ($fstart +1);
:set fend 0;
:put "Unidentified error";
}
}
:return {[]; []; []};
};
1. save the above script called ScriptFindPosix
2. in your script:
Code: Select all
/system script run ScriptFindPosix; # This command can be run when loading the router once to initialize the global variable FindRegex, which will store the search function
:global findPosix; # global variable declaration
#-----------------For example, find the date in the string -----
:local DateString "date: jan/01/2019 01:02:03";
:local regex "[a-z][a-z][a-z]/[01][0-9]/[0-2][0-9][0-9][0-9]";
:local startPosition 0;
:local ArrRezult [$findPosix $DateString $regex $startPosition ];
# return value: ArrRezult is array {FoundSubString ; PositionStart ; PositionEnd }
:local FoundSubString [:pick $ArrRezult 0];
:local FoundPositionStart [:pick $ArrRezult 1];
:local FoundPositionEnd [:pick $ArrRezult 2];
:put "DateString=$DateString"; # DateString=date: jan/01/2019 01:02:03
:put "FoundString=$FoundSubString"; # FoundString=jan/01/2019
:put "FoundPositionStart=$FoundPositionStart"; # FoundPositionStart=6
:put "FoundPositionEnd=$FoundPositionEnd"; # FoundPositionEnd=17
Code: Select all
:put [$findPosix "time 01:02:13 3:04:05" ("[0-2]\?[0-9]:[0-5]\?[0-9]:[0-5]\?[0-9]"."\$")]; # 3:04:05;15;22
:put [$findPosix "IP address: 192.168.0.0" ("[0-2]\?[0-9]\?[0-9]\?[.][0-2]\?[0-9]\?[0-9]\?[.][0-2]\?[0-9]\?[0-9]\?[.][0-2]\?[0-9]\?[0-9]\?")]; # 192.168.0.0;12;23
:put [$findPosix "IP address: 192.168.0.0/24" ("[0-2]\?[0-9]\?[0-9]\?[.][0-2]\?[0-9]\?[0-9]\?[.][0-2]\?[0-9]\?[0-9]\?[.][0-2]\?[0-9]\?[0-9]\?")]; # 192.168.0.0;12;23
:local IPMASKposix ("[0-2]\?[0-9]\?[0-9]\?[.][0-2]\?[0-9]\?[0-9]\?[.][0-2]\?[0-9]\?[0-9]\?[.][0-2]\?[0-9]\?[0-9]\?(/[0-3]\?[0-9])\?");
:put [$findPosix "IP address AND mask if exist: 192.168.0.1/32" $IPMASKposix ]; #192.168.0.1/32;30;44
:local IPMASKposix ("[0-2]\?[0-9]\?[0-9]\?[.][0-2]\?[0-9]\?[0-9]\?[.][0-2]\?[0-9]\?[0-9]\?[.][0-2]\?[0-9]\?[0-9]\?(/[0-3]\?[0-9])\?");
:local arrFound [$findPosix "IP address AND mask if exist: 192.168.0.1/32" $IPMASKposix ];
:put [:pick $arrFound 0] # 192.168.0.1/32