Using where to see if value is in an array

How are people scripting the use of the where statement to find a value in an array? (see example below)

In this example I am trying to see if a bridge VLAN contains an interface name in its array of untagged interfaces. The issue I have is terminating the value in the example below i.e.

untagged~($ifname . “;”)

  • If I do append the semi-colon then it works perfectly unless the value I’m looking for is the last one in the array, at which point it does not find it as the array does not end with a ;
  • If I don’t append the semi-colon to $ifname the match works like a starts with/partial match rather than matching the whole value in the array. For example if ifname=ether2 and untagged=ether1;ether20;bond1 the where statement below will match ether20 and output a 1 but it should be 0.
:if ([ /interface bridge vlan print count-only where bridge=$lifbridge vlan-ids=$nativevlan untagged~($ifname . ";"); ] > 0) do={ ... };

I’m getting around this currently by looping through each VLAN on the bridge that the interface is assigned to, and then looping through each interface in tagged/untagged.

P.S> Unrelated but fingers crossed that Mikrotik add an "else if " command to RouterOS

Hi,

~ tries to do a regex match on the value as a string.
You can build your regex to ensure it only matches required result : “whatever(;|$)”

i.e.

global matcher do={
local string "ether11;ether2;ether21;ether22"
if ($string~($1."(;|\$)")) do={
put ("$1 is in string")
} else {
put ("no match")
}
}

results :

[sini@sini2] > $matcher ether2
ether2 is in string
[sini@sini2] > $matcher ether1
no match
[sini@sini2] > $matcher ether22
ether22 is in string

fixed some errors on example…

:global matcher do={
    :local string "ether11;ether2;ether21;ether22"
    :if ( $string~"$1(;|\$)" ) do={
        :put "$1 is in string"
    } else={
        :put "no match"
    }
}

untagged~(“test;”) match anything that contain “test;”
untagged~(“test”) match anything that contain “test”
“test(;|$)” match anything that contain “test;” or end by “test”

“(^|;)test(;|$)” match exactly what: ( (start with test or the record start with test) and (the record end with test or end with test) )

so:

untagged~"(^|;)$ifname(;|\$)"


/interface bridge vlan
:if ([:len [find where bridge=$lifbridge and vlan-ids=$nativevlan and untagged~"(^|;)$ifname(;|\$)"]] > 0) do={
    :put "some VLANs found"
}

Thanks for replying @sin3vil and @rextended. For some reason I had it in my head that ~ was a partial match (aka contains vs = or !=) but I went back to the docs after posting my question here and saw it was actually regex as you say. But ran out of energy before testing it out.

Thanks for the example code! I will tweak the script now.

Cheers,

MC