findstr

Description

A custom iRule function which finds a string within another string and returns the string starting at the offset specified from the match.

Syntax

findstr <string> <search_string> [<skip_count> [<terminator count or string>]]

findstr <string> <search_string> [<skip_count> [<terminator>]]
  • Finds the string <search_string> within <string> and returns a sub-string based on the <skip_count> and <terminator> from the matched location. Note the following:
    • If the <skip_count> argument is not specified, it defaults to zero. If the <skip_count> argument is omitted, the <terminator> element must not be specified.
    • The <terminator> argument may be either a length or string of one or more characters.
    • If the <terminator> argument is not specified, it defaults to the end of the string.
    • This command, without <skip_count> or <terminator>, is equivalent to the following Tcl command:

string range <string> [string first <search_string> <string>] end

and may be delimited by whitespace only, by double quotes, or by curly braces. Single quotes are taken literally, rather than as delimiters, meaning that the match will fail if the search string is delimited with single quotes, and the match will extend to the end of the string if the termination character is delimited with single quotes (neither being the intended result.)
If either contain a double quote character, it can be escaped with a backslash immediately preceding the character, or by enclosing the entire string in curly braces {}. Either value may also be represented by a variable to take advantage of the natural delimiting they offer. (Don’t use curly braces to delimit variables or they won’t expand).

Examples

This iRule parses a session ID from the HTTP path and if found persists off of it using UIE persistence.
when HTTP_REQUEST {

   # Check for /install/ or /scripts/ in the path
   switch -glob [HTTP::path] {
      "*/install/*" {

         # Parse the URI "directory" after install. Look for /install/, skip 9 characters and match up to the next /.
         set session_id [findstr [HTTP::path] /install/ 9 /]
      }
      "*/scripts/*" {
         # Parse the URI "directory" after scripts. Look for /scripts/, skip 9 characters and match up to the next /.
         set session_id [findstr [HTTP::path] /scripts/ 9 /]
      }
      default {
         set session_id ""
      }
   }
   if {$session_id ne ""}{

      # Persist on the parsed session ID for X seconds
      persist uie $session_id 1800
   }
}

when RULE_INIT {
  set static::payload {<meta HTTP-EQUIV="REFRESH" CONTENT="0; URL=https://host.domain.com/path/file.ext?...&var=val">}
  set static::term {">}
  set urlresponse [findstr $static::payload URL= 4 $static::term]
  log local0. "urlresponse $urlresponse"
}

Parse the domain from a SIP header. Find the first @ instance, skip 1 character and read up until the first > or the end of the string.
log local0. "findstr output: [findstr "<sip:+12065551234@sip.example.com>" "@" 1 ">"]"
# Logs: findstr output: sip.example.com

Example using a multi-character terminator:
log local0. "findstr output: [findstr "aaa123456xxyz" "aaa" 3 "xyz"]"
# Logs: findstr output: 123456x