Forum Discussion

jay_41157's avatar
jay_41157
Icon for Nimbostratus rankNimbostratus
Sep 05, 2008

wildcard in data group.

Hi ,

 

 

I am trying to use \apple\* --> * being wildcard... but i do not have the correct fromat.. in the data group. is there an escape squence ?

 

thanks

6 Replies

  • If you're using a string datagroup, you don't need to escape the *. You can use apple* unquoted and unescaped. If you're evaluating the class with findclass (Click here), you don't need to use a wildcard though.

     

     

    Aaron
  • I am using string data group, but I have matchclass instead of findclass, and when I use apple* --> it does not use the apple"*" as the wildcard.

     

     

    Thanks
  • Does matchclass work with a * in the datagroup? I'm guessing not.

    If not, you could either replace the class with a switch statement and use the glob flag for wildcard matching, or if you like the class, you could replace matchclass with a foreach loop:

      
      when RULE_INIT {  
        
          Create a test class (actually a list in this case)  
         set ::test_class [list abcd abcde abcdef* abcdefg*]  
        
         foreach element $::test_class {  
        
            log local0. "Current \$element: $element"  
        
            if {[string match -nocase $element "ABCDEFG"]}{  
        
               log local0. "Matched \$element: $element.  Exiting loop."  
               break  
            }  
         }  
      }  
      

    Log output:

    Rule : Current $element: abcd

    Rule : Current $element: abcde

    Rule : Current $element: abcdef*

    Rule : Matched $element: abcdef*. Exiting loop.

    Aaron
  • Thanks, I just read the wiki on matchclass that indicates what you said about * in datagroup not wokring with match class, so I am guess a more cleaner approach might be to use findclass as you initially mentioned in the irule:

     

     

    Current IRULE:

     

    --------------------------------------------------------------------------------------------------------------------------------

     

    if { (not [matchclass [string tolower [HTTP::uri]] starts_with $::LegacyExceptions])

     

    and ([matchclass [string tolower [HTTP::uri]] equals $::LegacyPaths]) } {

     

    --------------------------------------------------------------------------------------------------------------------------------

     

    New:

     

    --------------------------------------------------------------------------------------------------------------------------------

     

    if { (not [findclass [string tolower [HTTP::uri]] $::LegacyExceptions] ==0 )

     

    and ([findclass [string tolower [HTTP::uri]] $::LegacyPaths] == 0) } {

     

     

     

     

    Or is there a better way to use findclass ? I am unsure about the syntax.
  • I think this might be more accurate for syntax..

     

    if { (not [catch[findclass [string tolower [HTTP::uri]] $::pubsLegacyExceptions] == 0] )

     

    and ([catch[findclass [string tolower [HTTP::uri]] $::pubsLegacyPaths] == 0 ]) } {

     

    not too sure on the result of catch..
  • Catch is used to trap runtime errors. The only benefit for using catch with findclass is handling the TCL error if the class isn't defined.

     

     

    Here is a quick example:

     

     

      
          return 0 is false.  Save the result of running the command 'return 0' to the variable named result  
         if {[catch {return 0} result]}{  
            log local0. "catch was true, because return resulted in return code 0. Result: $result"  
         } else {  
            log local0. "catch was false, because return resulted in non-zero return code. Result: $result"  
         }  
        
         if {[catch {set ::test 1} result] }{  
            log local0. "catch was true, because the set command returned with an error. Result: $result"  
         } else {  
            log local0. "catch was false, because the set command returned without error. Result: $result"  
         }  
        
         if {[catch {set ::test $doesnt_exist} result] }{  
            log local0. "catch was true, because the set command returned with an error. Result: $result"  
         } else {  
            log local0. "catch was false, because the set command returned without error. Result: $result"  
         }  
      

     

     

    And the log output:

     

     

     

    Rule : catch was true, because return resulted in return code 0. Result: 0

     

    Rule : catch was false, because the set command returned without error. Result: 1

     

    Rule : catch was true, because the set command returned with an error. Result: can't read "doesnt_exist": no such variable

     

     

     

     

    As for using findclass to support wildcard matching, I don't think it will work. findclass does do wildcard matching, but the URI token listed in the class would need to be as long or longer than the requested URI. For a class which contains five elements:

     

     

      
      test_class:   
         /aaaaa  
         /bbbbb  
         /ccccc  
         /ddddd  
         /aaaaa/test  
      

     

     

    Here is an iRule which attempts to match a requested URI of /aaaaa/t against the class:

     

     

      
      when RULE_INIT {  
         set ::uri "/aaaaa/t"  
        
         log local0. "Test URI: $::uri; \$::test_class: $::test_class ([llength $::test_class])"  
        
         log local0. "\[findclass \$::test_class \$::uri\]: [findclass $::test_class $::uri]"  
        
         log local0. "\[findclass \$::uri \$::test_class\]: [findclass $::uri $::test_class]"  
        
      }  
      

     

     

    The log output shows that /aaaaa/t matches the class element, /aaaaa/test. A requested URI of /aaaaa/test does not match against a class element of /aaaaa/t.

     

     

     

    Rule : Test URI: /aaaaa/t; $::test_class: /aaaaa /bbbbb /ccccc /ddddd /aaaaa/test (5)

     

    Rule : [findclass $::test_class $::uri]:

     

    Rule : [findclass $::uri $::test_class]: /aaaaa/test

     

     

     

     

    I think the easiest way of accomplishing wildcard matching is to use a foreach loop:

     

     

      
           set test_uri "/ABCDEFG"  
           log local0. "\$test_uri: $test_uri"  
            Create a test class (actually a list in this case)    
           set ::test_class [list /abcd /abcde /abcdef* /abcdefg*]    
            
           foreach element $::test_class {    
            
              log local0. "Current \$element: $element"    
            
              if {[string match -nocase $element $test_uri]}{    
            
                 log local0. "Matched \$element: $element.  Exiting loop."    
                 break    
              }    
           }   
      

     

     

    And the log output:

     

     

     

    Rule : $test_uri: /ABCDEFG

     

    Rule : Current $element: /abcd

     

    Rule : Current $element: /abcde

     

    Rule : Current $element: /abcdef*

     

    Rule : Matched $element: /abcdef*. Exiting loop.

     

     

     

     

    Aaron