Forum Discussion

Richard_Jones's avatar
Richard_Jones
Icon for Nimbostratus rankNimbostratus
Jun 22, 2011

Different results from TCL regexp and iRules regexp

I am working on an iRule that will validate the value of a parameter only contains a-z, 0-9, and / + =. I have created a regexp pattern that works in TCL, but not in an iRule:

 

 

TCL:

 

 

% regexp {^(?:[a-z0-9/+=]+)$} 1324

 

1

 

% regexp {^(?:[a-z0-9/+=]+)$} asdf

 

1

 

% regexp {^(?:[a-z0-9/+=]+)$} wqer!

 

0

 

% regexp {^(?:[a-z0-9/+=]+)$} asfd/

 

1

 

 

iRule:

 

 

log local0. "Val: $decoded_val"

 

set res [regexp {^(?:[a-z0-9/+=]+)$} $val]

 

log local0. "Res: $res"

 

 

Output:

 

 

Rule validate_param : Val: 1324

 

Rule validate_param : Res: 0

 

Rule validate_param : Val: asdf

 

Rule validate_param : Res: 0

 

Rule validate_param : Val: wqer!

 

Rule validate_param : Res: 0

 

Rule validate_param : Val: asfd/

 

Rule validate_param : Res: 0

 

 

The same regexp pattern matches the correct 3 entries when run via tclsh, but doesn't match anything correctly when run through an iRule. Ideas??

 

 

I realize that regexp isn't the most efficient, so I'm open to other alternatives as well.

 

 

Thanks

 

 

Richard

 

  • I'm not seeing the issue:

    
    when RULE_INIT {
    foreach x [list "1234" "asdf" "wqer!" "asfd/"] {
    log local0. "Val: $x"
    set res [regexp {^(?:[a-z0-9/+=]+)$} $x]
    log local0. "Res: $res"
    }
    }
    
    Jun 21 22:57:12 local/tmm info tmm[5091]: Rule regexp_test : Val: 1234
    Jun 21 22:57:12 local/tmm info tmm[5091]: Rule regexp_test : Res: 1
    Jun 21 22:57:12 local/tmm info tmm[5091]: Rule regexp_test : Val: asdf
    Jun 21 22:57:12 local/tmm info tmm[5091]: Rule regexp_test : Res: 1
    Jun 21 22:57:12 local/tmm info tmm[5091]: Rule regexp_test : Val: wqer!
    Jun 21 22:57:12 local/tmm info tmm[5091]: Rule regexp_test : Res: 0
    Jun 21 22:57:12 local/tmm info tmm[5091]: Rule regexp_test : Val: asfd/
    Jun 21 22:57:12 local/tmm info tmm[5091]: Rule regexp_test : Res: 1
    

    Perhaps the variable in the regexp should be $decoded_val?
  • You could also simplify the regex slightly by removing the parens as you're not using the capture group anyhow.

     

     

    set res [regexp {^[a-z0-9/+=]+$} $x]

     

     

    Aaron
  • hoolio, I made your change. Thanks. My regex-fu is weak these days....

     

     

    Jason, thanks for the quick demo, which I duplicated with my iRule and verified with plain text.

     

     

    The parameter value I'm inspecting is actually base64 encoded. I extract the value, base64 decode it, then run it through the regex. My log statement shows that I am correctly decoding the value. Just now, I added additional text to the end of a log statement and see that my base64 decoded string is actually "asdf ". I hadn't noticed that space last night....

     

     

    Now I just need to strip that space, and I should be good to go.

     

     

    Thanks for the help!

     

     

    R

     

  • Now that you've figured out the regex option you could try using scan as well. scan is typically more efficient than a regex.

       if {[scan $str {%[a-z0-9/+=]} match] and $match eq $str}{
          log local0. "matched $str"
       } else {
          log local0. "no match for $str"
       }
    

    foreach str [list "1234" "asdf" "wqer!" "asfd/"] {
       if {[scan $str {%[a-z0-9/+=]} match] and $match eq $str}{
          log local0. "matched $str"
       } else {
          log local0. "no match for $str"
       }
    }
    

    matched 1234

    matched asdf

    no match for wqer!

    matched asfd/

    Aaron