Regular Expressions

Regular expressions (regex, regexes) are at the heart of dialplan, and used in many other parts of FreeSWITCH configuration.

They are an uber-clever way to analyze, slice, dice, and massage text strings. We in FreeSWITCH we use the best and brightest, the greatest regular expressions of them all: Perl Compatible Regular Expressions (PCRE). Isn't that beautiful? It is.

A regular expression checks if a string matches a pattern (the pattern being the regex). A regular expression can also substitute parts of the strings with something else. Also, regular expressions can "select" a part of a string, and reuse it in returning the result.

In dialplan regexes are used to define the "expression" criterion of the "condition" tag.

The construct most used in FreeSWITCH demo dialplan is as follows:

<extension name="giovanni_03"> 
   <condition field="destination_number" expression=""^(1234)$"> 
         <action application="log" data="WARNING this is $1"/> 
   </condition> 
</extension> 

If we insert this extension at begin of default.xml demo dialplan, reloadxml, and then call 1234, we have a condition that matches if the destination_number channel variable string value is exactly "1234" (will not match a longer string). This regex has caret (^) as first character, meaning "beginning of string", dollar sign ($) as last character, meaning end of string, and some characters in between, enclosed by round parenthesis. Round parenthesis grab what's inside them, and put it in a "register". In this case, they put 1234 in register $1 (if there were a successive couple of parenthesis, they would put the grabbed text into the $2 register. And so on, and so on.

Let's look at a more complex use of regular expression:

<extension name="giovanni_04"> 
   <condition field="destination_number" expression="^1800(\d{3})(\d{2}).*$"> 
            <action application="answer"/>   
         <action application="log" data="WARNING this is $1 and this is $2"/> 
         <action application="hangup"/> 
   </condition> 
</extension> 

Insert the extension at beginning of default.xml dialplan, then reloadxml and call 18009876543.
Your output will be similar to the following:

The expression we used in condition, "^1800(\d{3})(\d{2}).*$", can be read as: this condition matches if the field (destination_number) string value begins with 1800 then three digits then two digits then whatever until end of string. The first three digits after 1800 will be put into $1 register (first parenthesis pair), the following two digits into the $2 register.

The content of the registers persist only inside the present condition opening and closing tags.

The following are some sample regular expressions and their meanings:

We can test regular expressions from the FreeSWITCH command line, to be sure they do what we want.

The regex FreeSWITCH console command needs at least two arguments: the data to test and the pattern to match against. The arguments are separated by a | (pipe) character. The regex command will return true if the data and the pattern match, otherwise it will return false. You can try the following examples at fs_cli:

freeswitch@internal> regex 1234|\d

true

freeswitch@internal> regex 1234|\d\d\d\d

true

freeswitch@internal> regex 1234|\d{4}

true

freeswitch@internal> regex 1234|\d{5}

false

freeswitch@internal> regex 1234|^1234$

true

freeswitch@internal> regex 1234|234

true

freeswitch@internal> regex 1234|^234

false

The regex command also has a capture syntax that will store and return the registers' values. The expression %0 contains the entire matched value whereas %1 contains the first register, %2 contains the second, and so forth.

    freeswitch@internal> regex 18005551212|1?(\d\d\d)(\d\d\d)(\d\d\d\d)
    true
    freeswitch@internal> regex 18005551212|1?(\d\d\d)(\d\d\d)(\d\d\d\d)|%0
    18005551212
    freeswitch@internal> regex 18005551212|1?(\d\d\d)(\d\d\d)(\d\d\d\d)|%1
    800
    freeswitch@internal> regex 18005551212|1?(\d\d\d)(\d\d\d)(\d\d\d\d)|%2
    555
    freeswitch@internal> regex 18005551212|1?(\d\d\d)(\d\d\d)(\d\d\d\d)|%3
    1212
    freeswitch@internal> regex 18005551212|1?(\d\d\d)(\d\d\d)(\d\d\d\d)|%1%2%3
    8005551212
    freeswitch@internal> regex 18005551212|1?(\d\d\d)(\d\d\d)(\d\d\d\d)|%1-%2-%3
    800-555-1212
    freeswitch@internal> regex 18005551212|^7|%0
    18005551212
  

For more regex documentation, Internet is full of tutorials on how to use Perl Regular Expressions (regexes), and there is a beautifully crafted page in Confluence especially for use in FreeSWITCH. Search http://freeswitch.org/confluence for "regular expression".