Forum Discussion
David_Noonan_67
Nimbostratus
Oct 08, 2007Syntax for "matches" and "matches_regex"
We've got an iRule that contains the following code. It works fine but I find the repetition offensive.
elseif {[HTTP::uri] contains "fx1"} {
use pool Xyzzy
}
elseif {[HTTP::uri] contains "fx2"} {
use pool Xyzzy
}
elseif {[HTTP::uri] contains "fx3"} {
use pool Xyzzy
}
elseif {[HTTP::uri] contains "fx4"} {
use pool Xyzzy
}
I thought this could be replaced with something like this
elseif {[HTTP::uri] matches "fx[1234]"} {
use pool Xyzzy
}
but it complains about"extra tokens at end of expression". So I tried this
elseif {[HTTP::uri] matches_regex "fx[1234]"} {
use pool Xyzzy
}
But that complains about an undefined procedure.
Can someone point me at a working example of the matches and/or matches_regex using a character range? The examples shown on the wiki are overly simple and therefore not very useful.
Thanks
6 Replies
- Deb_Allen_18Historic F5 AccountUse {} to delimit the match expression instead of "" and you should be good to go:
(wiki example updated)elseif {[HTTP::uri] matches_regex {fx[1234]}} { use pool Xyzzy }
/deb - Deb_Allen_18Historic F5 Accountboy, some funky substitution is taking place there....
that should read:
open brace, fx, open square, 1234, close square, close brace
with no commas or whitespace.
/deb - Deb_Allen_18Historic F5 AccountJust realized you'd have to also include some wildcards if you want to simulate the "contains" command:
elseif {[HTTP::uri] matches_regex {.*fx[1234].*}} { use pool Xyzzy }
which should read:
open brace, period, asterisk, fx, open square, 1234, close square, period, asterisk, close brace
/deb - Deb_Allen_18Historic F5 AccountBraces may be used to prevent interpretation of strings surrounded by [] as commands, as you experienced ("undefined procedure").
As long as there isn't a variable inside the braces that requires expansion, you can use them in most cases instead of "", and they can actually be more efficient, if harder to type & read.
Colin wrote an excellent tech tip recently about using {} with numbers to prevent the tcl interpreter from having to figure out if they are strings or not before performing the operation: http://devcentral.f5.com/Default.aspx?tabid=63&articleType=ArticleView&articleId=110 (Click here)
(Someday I'm going to have to go re-work all of my codeshare examples to take advantage of that optimization...)
HTH
/deb - hoolio
Cirrostratus
Deb, thanks for the link to Colin's tips on avoiding conversions...
noonand, you could also use string wildcards to do this and avoid the more expensive regex evaluation. Here's an example using string match:elseif {[string match {*fx[1-4]*} [HTTP::uri]]} { pool Xyzzy }
If you're doing multiple URI tests, it would probably be faster to use a switch statement:when HTTP_REQUEST { switch -glob [HTTP::uri] { {*fx[1-4]*} { pool test_http_200_pool} } }
As Deb said, the string should read:
open brace, asterisk, "fx", open square, 1-4, close square, asterisk, close brace
Aaron - Deb_Allen_18Historic F5 AccountLooks like Joe fixed the character display substitution issue - thanks Joe!
Great points, hoolio. Definitely more optimal approach. I didn't realize you could use charsets with either string match or switch.
I just came back to point out that for the regex with braces, you can instead escape the [] with a backslash to prevent the interpreter from trying to execute as a command:if {"testfx4xxx" matches_regex ".*\[1234\].*"} {
/deb
Recent Discussions
Related Content
DevCentral Quicklinks
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
Discover DevCentral Connects
