Home » Skype for Business » Understanding Skype for Business Normalizations and Regular Expressions

Understanding Skype for Business Normalizations and Regular Expressions

If you are like me, then understanding normalization rules can be challenging if you don’t quite fully understand the syntax. For the longest time I thought the syntax was written by some Mayan tribe and often relied on intelligent tools or regex libraries online to grab the rules I wanted. Then one night, I was lying in bed and the penny dropped and now while I do not profess to be an expert in regex I now know enough to get through normalisation rules in Skype for Business and wanted to share what little knowledge I have with you.

There are many websites out there that try to explain regex in the simplest and most difficult terms. For me, I do not need to understand character normalisation, just number, so that should be simple right?

Let’s strip back the basics of what we need to understand to formulate an E.164 number for Skype for Business

  • We need to be able add + to the beginning of every dialled number
  • We need to be able to drop all leading 0 (zeroes) from dialled numbers
  • We need to be able to translate local subscriber numbers into full e.164 numbers
  • We need to translate internal extension numbers into full Telephone URIs
  • We need to translate international numbers
  • We need to exclude emergency numbers from any normalisation

Now that we know roughly the conditions we need to account for, let’s look at the regex syntax in as much detail as we need to know for Skype for Business. In regex, all characters match themselves except for the following special characters:


Regex supports wildcards and the character . (period) is used to declare a wildcard. This means literally, accept any character and is used in circumstances where we perhaps do not need to perform any translations because we can guarantee the string is in the correct format. Such as on upstream SBCs.

Anchors are characters that denote the beginning or end of a string.

^ = denotes the beginning of a string

$ = denotes the end of a string

With Skype for Business rules we always start the regex with ^ followed by the pattern and end with $ for instance

A useful special character set is the open and close parenthesis (), these act as a Marked Group which can be later referenced in your translation. Any pattern within the open and closed parenthesis are considered to belong together and are treated as a number block. For instance (1234) would be treated as a group of numbers that you can use later.

With regex you do not need to declare every single instance of a number. For example, a UK telephone number is 11 digits long. We do not need to reference 01234567890 in regex, we can use shorthand character classes and repeaters to cover that in as little as 4 characters.

\d = matches a numeric digit (0 to 9)

There are more, but for Skype for Business we do not need to know about them.

Repeaters are characters that tell regex to repeat the preceding character within the boundaries set.

* = means match the preceding character zero to unlimited times

+ = means match the preceding character one to unlimited times

{n} = means match the preceding character exactly n times

{n,m} = means match the preceding character at least n times and at most m times

{n,} = means match the preceding character at least n times to unlimited times

? = means the preceding character can optionally match

Another useful special character is the pipe character |. This can be used to match the characters either side of the | character. For example,

123|456 = can match either 123 OR 456 but not 123456

One final special character is the bracket expression, starting with [ and ending with ]. Numbers within [] represent a number block and can contain their own unique matching rules.

The last bit we need to understand is back references for our translation rules. How do we reference the pattern match and build our translations from them? We use the $ character in our translations. The $ character references the entire pattern if you have no marked groups and is accompanied by an integer to denote which group to add. For instance, if your regex was this ^\d{6}$ and we referenced $1 in the translation rule we would get the following output 123456. If we used marked groups for example, ^(\d{3})(\d{3})$ and we referenced $2 in our translation rule, we would get the following output 456.

Now we know the basics of regex we can start building our normalisation rules for Skype for Business.

Name Dialled Example Pattern Translation Translation Example
Internal Extensions 501 ^(5\d{2})$ +441270897$1 +441270897501
Local Numbers (no area code) 214067 ^(\d{6})$ +441270$1 +441270214067
UK National Numbers 01745826610 ^0([1-6]\d{9,10})$ +44$1 +441745826610
UK Mobile Numbers 07975730199 ^0(7\d{9})$ +44$1 +447975730199
UK Freephone Numbers 08001233000 ^0(800\d{6,})$ +44$1 +448001233000
UK Premium Rate Numbers 0906661911 ^0(9\d{8,9})$ +44$1 +449066611911
UK Non Geographic Numbers 08451235678


^0(8[4|7]\d{6,})$ +44$1 +448451235678 or
+448431235678 or
+448711235678 or
+448721235678 or
International Numbers 004915512356789


^00(\d{2})0?(\d{9}\d+)$ +$1$2 +4915512356789
UK Emergency Numbers 999
^(999|111)$ $1 999


Using these simple normalisation rules, you can account for and route numbers that match these patterns using Skype for Business. You can improve these patterns to be stricter, however, I prefer to match the beginning of the number and then send to the gateway. If the number is not in use or the user has dialled an incorrect number it is a better user experience to get prompted from the provider about this rather than receive a Skype for Business unavailable tone (IMO).

How to add these rules to Skype for Business? The built in UI for normalisation rules will be able to do some of these translation rules for you. However, more advanced rules will need to be added using PowerShell. The following example assumes you have a site dial plan already configured.

New-CsVoiceNormalizationRule -Name “Internal Extensions” -Description “Rule for Internal Extensions” -Parent “Site:HQ” -Pattern “^(5\d{2})$” -Translation “+441270897$1” –IsInternalExtension:$True

I good tool for learning and testing your expressions is Expresso made by Ultrapico http://www.ultrapico.com/Expresso.htm best of all its FREE! You can use this tool to build and test your own regex expressions for use with Skype for Business.

Lastly, a word on internal extension numbers. This is quite important when setting up enterprise voice. Skype for Business allows you to configure a DID and an extension number for each individual user e.g.


Out of the box, Skype for Business will not allow extension dialling without a normalisation rule. Furthermore, the extension number should relate to the users DID as in the above example. The normalisation rule in the table above called “Internal Extensions” would apply if you selected the Internal Extensions tick box on the rule.

However, if you are in an unfortunate position where your extension numbers in no way relate to the users DID e.g.


Then you are in the position where by you would have to create a normalisation rule for specific user that has unrelated extension numbers. This would be very tedious for large deployments, so you may want to use this point to change the way people use extensions. In my experience this does not matter so much because most internal communication is done via the Skype for Business desktop app that uses SIP addresses rather than numbered extensions. However, for desk phone users, extension dialling is still the prevalent dialling mechanism.



  1. Hi Mark,

    I was wondering if you have any idea why this would be happening.
    We have our telephone format in active directory like this: +44 2891 222222 X 1234
    With Lync 2013 and Lync 2013 client this worked fine. You could click call on the user’s telephone number and it would always call their extension number.
    When the update for Office 2013 that was released which updated Lync 2013 to Skype for business this still worked fine.

    However I have now installed Office 2016 and Skype for business 2016 is installed and now this feature has broken.
    When i type that format of number in, i’m getting only the last digit showing, so 4 is being dialled.
    Our backend server is still Lync 2013.

    I’ve tested the normalisation rules using Abserver.exe and everything still looks fine from the server side.

    Thanks for any help you can provide,

  2. We have a few users that have the extension filled into the IP Phone attribute and yes it works properly.
    We have a normalisation rule in the text file, and it normalises the number correctly.

    ABServer.exe -testphonenorm “+442891222222X1234”
    +442891222222X8201 -> tel:+442891222222;ext=1234
    Matching Rule in Company_Phone_Number_Normalization_Rules.txt on line 15

    I noticed on a few more users that it shows 2 numbers on their list eg:
    Work: +44 28 9122 2222 X 1234
    Work: +442891222222

    If only i could get it to populate another below with the extension number eg:

    Work: +44 28 9122 2222 X 1234
    Work: +442891222222
    Work: 1234

    That would be the perfect solution 🙂

    Thanks for your help.

    • Hi

      I have been playing around with this myself. I have a Sfb 2015 back end server with Office 2016 (sorry no time to reinstall 13 🙂 ).

      Here is my example in AD

      Contact A
      Telephone: +441274251950 X 251950

      My Rule

      Pattern = ^\++(\d{10,13})\s?\D\s?(\d{6})$ (overkill on spaces but passed validation)
      Translation = +$1;ext=$2

      Running James Cussen’s S4B Address book normalization tool (www.myskypelab.com) the correct rule is matched against the AD input.

      Looking at the client Log I can see this

      ERROR :: SIP_URL::InternalInitialize ParseSipUrl(sip:+441274251950;ext=251950) failed 80ee0012

      I think the error isn’t about it not displaying correctly and more to do with presence. BUT, from this log I can clearly see that the ABS is formatting the telephone field as expected, just the client cannot display it.

      At this moment, it is probably a bug I would imagine and if the SfB 2015 client worked then best to revert to that and wait for Office 2016 to mature.

      Sorry couldn’t help much further.


  3. I’ve recently had to deal with quite possibly the most ridiculously complex dial plan – I thought you may find it vaguely entertaining. Imagine the scenario – that you mention – where the user’s DDI is disjointed from their extension. Example +442077904500;ext=1001. Where the extension is effectively the employee ID.

    Users need to be able to dial full DDI and the user’s extension. Sigh. But doable, just lots of PowerShell translation scripting in the Dial-plan, and of course some address book stuff as the numbers are referenced in the AD.

    Now, as if this scenario couldn’t get any worse….Add in a global Mitel deployment. In the Mitel deployment we *have* to dial with the short-code 4 digit, and receive on the 4 digit extension.

    We now have translation rules coming out of our ears.

    It all works, but man is it an effort to add new people.

    You have:

    Address book translations
    Dial-plan translations
    Routing out to the SONUS translations
    Routing outbound to the Mitel translations
    Routing inbound from the Mitel translations

    …and I’ve got a headache. I’m just pleased I don’t have to manage this one in the future 🙂

  4. Hi Mark, i hope you can help me because i cant anything in the internet regarding to my problem. In Germany we have meanwhile phonenumbers up to 17 digits. We cant call these numbers. Is Skype unable to route these numbers ?

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: