Forum Discussion

KT_271103's avatar
KT_271103
Icon for Nimbostratus rankNimbostratus
Sep 27, 2016

LTM

Can anyone give explanation on below if {[string first "PRIV" $vs] == "0"}{ regsub {_VIP$} $vs "" parser } else { regsub {_PERMVIP$} $vs "" parser } set counter [llength [split $parser "_"]] set appporttype [getfield $parser "_" $counter] regsub $appporttype$ $parser "" parser1 regsub {_$} $parser1 "" parser

 

3 Replies

  • Reformatting for readability:

     

    if { [string first "PRIV" $vs] == "0"} { 
        regsub {_VIP$} $vs "" parser 
    } else {
        regsub {_PERMVIP$} $vs "" parser 
    }
    set counter [llength [split $parser "_"]] 
    set appporttype [getfield $parser "_" $counter] 
    regsub $appporttype$ $parser "" parser1 
    regsub {_$} $parser1 "" parser
    

     

    The first if conditional checks to see if the variable $vs (which is set somewhere above the code block you provided) starts with the string "PRIV" (in an iRule, it is generally better to say if { $vs starts_with "PRIV" }, by the way). To be pedantic, string first $needle $haystack returns the offset (starting at 0) of the first instance of $needle in $haystack (or -1 if it is not found). So, this checks if PRIV is at offset 0 (meaning at the beginning) of the string referenced by $vs.

    If the value referenced by the variable $vs starts with "PRIV", then it strips the string literal _VIP from the end of the value in $vs, assigning the resulting value to a variable named "parser". Pedantically, regsub exp str subst var evaluates the regular expression "exp" against the variable "str" and replaces a match with "substr", assigning the value to "var". In this code, "exp" is {_VIP$}. Squirly braces ({...}) are non-interpolating quote operators (so they are just quotes around a string) and the actual expression is _VIP$. In Tcl regexp, the dollar-sign ($) at the end means "match the preceding string (_VIP, in this case) if-and-only-if it is at the very end". (For what it's worth, regular expressions should generally be avoided in iRules. This same function can be done a number of different ways, but a reasonably easy one is: set parser [string range $vs 0 [expr { [string last "_VIP" $vs] - 1 }]]. That might look nasty, but it takes half the execution time of the regsub method).

    If the value referenced by the variable $vs does not start with the literal PRIV, then the else clause code strips the literal _PERMVIP from the end of the value referenced by $vs, and sets the result to the variable "parser".

    Said very briefly, then: if the string referenced by $vs starts with PRIV, strip _VIP from the end of that string and assign the result to $parser; otherwise, strip _PERMVIP from the end of that string and assign the result to $parser.

    The next line treats the value of the variable $parser as a series of labels delimited by underscores (_). It sets a variable called "counter" to the number of such labels. The line after that gets the last label and assigns it to a variable called "appporttype" (again, for what it's worth, since the split was already done on the previous line, these two lines could have been reduced to: set appporttype [lindex [split $parser _] end]).

    The next line two lines remove the last label from the string apppporttype and assigns the value back to the variable called "parser".

    Okay, putting it all together: if, at the start of this block, $vs is "PRIV_ABC_DEF_VIP", then, at the end, $parser will be "PRIV_ABC". It stripeed _VIP from the end (because it starts with PRIV_), then removes the label before _VIP (_DEF, in this example).

    Were I writing this logic, I might do something like this instead:

     

    if { $vs starts_with PRIV } {
         remove _VIP from the end of $vs
        set parser [string range $vs 0 [expr { [string last "_VIP" $vs] - 1 }]]
    } else {
         remove _PERMVIP from the end of $vs
        set parser [string range $vs 0 [expr { [string last "_PERMVIP" $vs] - 1 }]]
    }
    
     remove the last label that starts with underscore (_) from $parser
    set parser [string range $parser 0 [expr { [string last _ $parser] - 1 }]]
    

     

    (An alternative to the last line -- and keeping with the list creation in the original -- could be: set parser [join [lrange [split $parser _] 0 end-1] _], but that is quite a bit slower).

    • KT_271103's avatar
      KT_271103
      Icon for Nimbostratus rankNimbostratus

      Thanks Vernon for given good explanation in the first part if condition. But still I could not understand the below statement.

       

      The next line treats the value of the variable $parser as a series of labels delimited by underscores (_). It sets a variable called "counter" to the number of such labels. The line after that gets the last label and assigns it to a variable called "appporttype" (again, for what it's worth, since the split was already done on the previous line, these two lines could have been reduced to: set appporttype [lindex [split $parser _] end]).

       

      The next line two lines remove the last label from the string apppporttype and assigns the value back to the variable called "parser".

       

      I hope you said above statement for below codes set counter [llength [split $parser "_"]] set appporttype [getfield $parser "_" $counter] regsub $appporttype$ $parser "" parser1 regsub {_$} $parser1 "" parser

       

  • I will illustrate with an example. Considering just this code:

     

    1: set counter [llength [split $parser "_"]] 
    2: set appporttype [getfield $parser "_" $counter] 
    3: regsub $appporttype$ $parser "" parser1 
    4: regsub {_$} $parser1 "" parser
    

     

    I added line number for clarity. Assume that, right before this code executes, $parser is "PRIV_ABC_DEF_001".

    After line 1, $counter will contain the value 4. That's because it treats the value in $parser to be a set of fields separated by underscores. Thus, there are four fields, namely the set ("PRIV", "ABC", "DEF", "001").

    After line 2, $appporttype will equal "001" because it is the last label in $parser, again, treating it as a string of fields delimited by underscores.

    After line 3, $parser1 will be "PRIV_ABC_DEF_", because it is the value of $parser with the last field removed.

    After line 4, $parser will be "PRIV_ABC_DEF", because it strips the trailing underscore from $parser1 and assigns the result back to $parser.