Regex for one single outbound route (UK)

Status
Not open for further replies.

Adrian Fretwell

Well-Known Member
Aug 13, 2017
1,383
364
83
Please don't take this post too seriously, I was just having some fun playing with regular expressions.

I wanted to create a regular that would allow me to dial:
999 for the emergency services.
9999 for the emergency services but stripping the initial 9.
0xxxxxxxx etc. for national numbers.
44xxxxxxxx etc. for national numbers.
00xxxxxxxxx etc. for international numbers.
90xxxxxxxx etc. for national numbers but stripping the 9.
900xxxxxxxxx etc. for international numbers but stripping the 9.
9xx etc. for local numbers but stripping the 9 (101 - police non emergency, 106 - power companies etc.).

So here it is...
Code:
^9?((?:999)|(?:[04](?(?<=4)4\d{9,17}|\d{9,17}))|(?:(?<=9)[^9]\d{2,17}))$


And this is me trying to explain how it works:

The ^ anchors the pattern to the beginning of the line

9 literally matches a 9

? is a quantifier that causes the group to be matched zero or one times, but giving back if matched further in.

( starts the first capturing group and runs right up to the $ end of line anchor. This provides the digits that end up in $1

(?:999) creates a non capturing group that literally matches 999. The ?: makes it non capturing All these inner groups are not capturing because we only want a result in $1, we do not want a $2, $3 etc.

| marks the start of the second matching alternative if 999 is not matched.

(?:[04](?(?<=4)4\d{9,17}|\d{9,17})) is the second non capturing group.

[04] is a character group that matches literally a 0 or a 4.

(? marks the start of a conditional statement

(?<=4) is a positive look behind for the literal 4, if it is...

then the next part of the match 4\d{9,17} requires a literal 4 followed by between 9 and 17 digits. This ensures a string starting with a 4 must be followed by another 4.

otherwise the next part of the match \d{9,17} requires between 9 and 17 digits.

| marks the start of the third matching alternative.

(?:(?<=9)[^9]\d{2,17}) is the third non capturing group.

(?<=9) is a positive look behind to say that the preceding digit must be a 9.

[^9]\d{2,17} this matches between 2 and 17 digits as long as the first digit is not a 9, this means it will not consume the 9 required by the 999 match.

) closes this non capturing group.

) closes the first capturing group.

$ anchors to the end of the line - and that's it!

Obviously having one single outbound route will not be practical in all situations ,like where Toll Allow is required or where all outbound calls are barred apart from the emergency services etc.

You can test the expression by pasting it in the box at https://regex101.com/

You can also test it using the regex API at the Freeswitch CLI (fs_cli). regex,<data>|<pattern>[|<subst string>][n|b]
If you do, user the m:~ modifier to change the default delimiter from the | (pipe) to a ~ (tilde).

Example:
Code:
freeswitch@standby-blue> regex m:~9123~^9?((?:999)|(?:[04](?(?<=4)4\d{9,17}|\d{9,17}))|(?:(?<=9)[^9]\d{2,17}))$

I hope some of this may help someone. Adrian.
 
Last edited:
Status
Not open for further replies.