Here's a critique of one pattern found in the library:
Pattern for UK landlines and mobiles
Your pattern:
^((\(44\))( )?|(\(\+44\))( )?|(\+44)( )?|(44)( )?)?((0)|(\(0\)))?( )?(((1[0-9]{3})|(7[1-9]{1}[0-9]{2})|(20)( )?[7-8]{1})( )?([0-9]{3}[ -]?[0-9]{3})|(2[0-9]{2}( )?[0-9]{3}[ -]?[0-9]{4}))$
is very inefficient and fails to match many valid UK numbers even when entered in the right format.
Many of the brackets are redundant.
----
The opening part:
^((\(44\))( )?|(\(\+44\))( )?|(\+44)( )?|(44)( )?)?((0)|(\(0\)))?( )?
has a few problems.
The (\(44\)) simplifies to \(44\) for example and ( )? should be \s? too.
The repetition of '44' is unecessary. After you've found it once, move on!
The 44 and the optional trailing space are common to all four options and should be stated only once.
The (\(44\))( )?|(\(\+44\))( )? 'OR' construct simplifies to \(\+?44\)\s? for example.
The (\+44)( )?|(44)( )?) 'OR' construct simplifies to \+?44\s? too.
Both of those then reduce to \(?(\+?44\)?\s?) with optional parentheses and spaces.
Don't insist the user enters balanced parentheses. It's the digits that matter.
When the user enters a number in international format, the pattern insists on a 0 after the +44. The 0 should not be there, but some people mistakenly type it. You should make the 0 optional, and with optional parentheses.
Without providing for a 0 after the +44, the opening part simplifies to:
which is optional opening parentheses followed by +44 and optional closing parentheses, then optional space and optional opening parentheses, OR initial optional opening parentheses followed by the 0 trunk code.
With provision for optional parentheses and a 0 after the +44 added back in it becomes:
^\(?(\+?44\)?\s?\(?(0\)?\s?\(?)?|0)
----
If you want to also allow 00 44 and 011 44 (as well as the usual +44 country code and 0 trunk code) along with parentheses, spaces and hyphens, and the optional (0) in optional parentheses after the +44 country code, try:
^\(?(?:(?:0(?:0|11)\)?[\s-]?\(?|\+)44\)?[\s-]?\(?(?:0\)?[\s-]?\(?)?|0)
for the opening part.
----
The remainder of your pattern:
(((1[0-9]{3})|(7[1-9]{1}[0-9]{2})|(20)( )?[7-8]{1})( )?([0-9]{3}[ -]?[0-9]{3})|(2[0-9]{2}( )?[0-9]{3}[ -]?[0-9]{4}))$
doesn't match all UK formats and has a few syntax issues, discussed below.
The [1-9]{1} should be just [1-9]. The {1} is redundant.
The ( )? should be \s? here.
----
The 'London' part of the pattern:
(.....|.....|(20)( )?[7-8]{1})( )?([0-9]{3}[ -]?[0-9]{3})|.....)
is problematical.
The literal (20) does not need to be in brackets, but isn't needed at all (see below).
The [7-8] should be [78] but note that London numbers also begin with 3 now [378].
The {1} is always redundant.
The [ -]? is better coded as [\s-]? as it is easy to accidentally add a rogue space or delete a needed space without noticing.
Your London pattern fails in other ways too.
It expects ...20 7 XXX XXX or ...20 8 XXX XXX which is also a digit short of reality and in a completely incorrect format. London numbers are 2+8 format (e.g. 020 3555 7788), not 3+6 or 2+7 or whatever this is.
There is no need for a London pattern. You need a pattern for all 02 numbers. All 02 numbers use 2+8 format.
This part (20)( )?[7-8]{1} of your pattern could be completely removed (read on).
----
This part of the pattern for 01 and 07 numbers:
(((1[0-9]{3})|(7[1-9]{1}[0-9]{2})|.....)( )?([0-9]{3}[ -]?[0-9]{3})|(.....))$
matches 01 and 07 numbers only in 4+6 format.
It fails to match valid UK 01 numbers in the real 3+7 (e.g. 0116 555 8888 or 0121 555 7777), 4+5 (e.g. 01750 62555), 5+5 (e.g. 015395 77888) and 5+4 (e.g. 016977 3888) formats.
No UK area codes begin 010, so the first 1[0-9]{3} could be 1[1-9][0-9]{2} if other adjustments were made later in the pattern, but there's a better way altogether (discussed at the end).
Amending the pattern to accept 5+4, 5+5, 4+5, 4+6 and 3+7 format numbers gives this:
(?:\d{5}\)?[\s-]?\d{4,5}|\d{4}\)?[\s-]?(?:\d{5}|\d{3}[\s-]?\d{3})|\d{3}\)?[\s-]?\d{3}[\s-]?\d{3,4})$
with provision for optional closing parentheses after the area code followed by optional hyphen or space.
The new pattern also provides for optional space or hyphen within the subscriber part of the number.
This part of the new pattern doesn't care what the leading digit is, so it allows numbers to be entered in the 'wrong' format (e.g. 01884 777 888 as 018 8477 7888, 020 3555 7788 as 02035 557 788 and 07788 555777 as 0778 855 5777, etc). Those that are entered in the wrong format should be corrected by a later process.
----
Your final chunk of code:
((.....|.....|.....)( )?(.....)|(2[0-9]{2}( )?[0-9]{3}[ -]?[0-9]{4}))$
looks like it should be matching 02 area codes, but it also has problems.
02 area codes use the 2+8 format (e.g. 020 8123 4567) but your pattern expects them to be entered in 3+7 format.
They should be able to be entered in either format (then corrected to 2+8 format for display).
Here's the correct pattern for 2+8 format:
\d{2}\)?[\s-]?\d{4}[\s-]?\d{4}
with provision for optional closing parentheses after the area code followed by optional hyphen or space.
It also provides for optional space or hyphen within the subscriber part of the number.
The long pattern in the previous section allows 02 numbers to be entered in 5+5, 4+6 or 3+7 format. If the user does that, the number should be corrected to the right format for display.
----
Do also consider replacing [0-9] with \d for readability; so that character groups are used only for reduced ranges.
Don't insist on mandatory brackets, allow them to be optional.
Don't insist on 'balanced' brackets on user input. As long as the user puts all the right digits in, the brackets really don't matter.
Don't restrict the format the user can use for input. If the user types 015 3957 7888 or 0153 957 7888 or 01539 577888 instead of 015395 77888, let them do that. All the digits are there. Reformat it correctly for display afterwards.
----
Testing
Your current pattern is this:
^((\(44\))( )?|(\(\+44\))( )?|(\+44)( )?|(44)( )?)?((0)|(\(0\)))?( )?(((1[0-9]{3})|(7[1-9]{1}[0-9]{2})|(20)( )?[7-8]{1})( )?([0-9]{3}[ -]?[0-9]{3})|(2[0-9]{2}( )?[0-9]{3}[ -]?[0-9]{4}))$
What your current pattern needs to match, and whether it does:
016977 3888 [5+4] - no
017687 55555 [5+5] - no
01750 62555 [4+5] - no
0175 062 555 (alt) - no
0175 062555 (alt) - no
01884 777 888 [4+6] - yes
01884 777888 [4+6] - yes
0116 555 7788 [3+7] - no
0191 777 8899 [3+7] - no
020 3555 7788 [2+8] - no
0203 555 7788 (alt) - yes
02035 557 788 (alt) - no
020355 57788 (alt) - no
024 7555 8899 [2+8] - no
074557 77888 (alt) - no
07555 777 888 [4+6] - yes
07555 777888 [4+6] - yes
0775 577 7888 (alt) - no
078 5577 7888 (alt) - no
(alt) means "alternative spacing that some people might use to enter a number".
While spaces are optional in your pattern, most of the parentheses are not but should be.
Since 03 numbers are charged at the same rate as 01 and 02 numbers, the pattern should also match those.
----
Some suggestions
Use the corrected opening part from above:
^\(?(?:(?:0(?:0|11)\)?[\s-]?\(?|\+)44\)?[\s-]?\(?(?:0\)?[\s-]?\(?)?|0)
then match numbers input in 5+4, 5+5, 4+5, 4+6, 3+6, 3+7, 2+8 format:
(?:\d{5}\)?[\s-]?\d{4,5}|\d{4}\)?[\s-]?(?:\d{5}|\d{3}[\s-]?\d{3})|\d{3}\)?[\s-]?\d{3}[\s-]?\d{3,4}|\d{2}\)?[\s-]?\d{4}[\s-]?\d{4})$
Actually, just realised there's another efficiency gain to be had by altering the order in the second part of the pattern so that shorter area codes match first.
Match numbers in 2+8, 3+6, 3+7, 4+5, 4+6, 5+4, 5+5 format:
(?:\d{2}\)?[\s-]?\d{4}[\s-]?\d{4}|\d{3}\)?[\s-]?\d{3}[\s-]?\d{3,4}|\d{4}\)?[\s-]?(?:\d{5}|\d{3}[\s-]?\d{3})|\d{5}\)?[\s-]?\d{4,5})$
Putting it all together:
^\(?(?:(?:0(?:0|11)\)?[\s-]?\(?|\+)44\)?[\s-]?\(?(?:0\)?[\s-]?\(?)?|0)(?:\d{2}\)?[\s-]?\d{4}[\s-]?\d{4}|\d{3}\)?[\s-]?\d{3}[\s-]?\d{3,4}|\d{4}\)?[\s-]?(?:\d{5}|\d{3}[\s-]?\d{3})|\d{5}\)?[\s-]?\d{4,5})$
Once you have matched the input format, extract the 44 country code in $1 (null if national format was used with 0 trunk code) and the NSN in $2 with this second pattern:
^\(?(?:(?:0(?:0|11)\)?[\s-]?\(?|\+)(44)\)?[\s-]?\(?(?:0\)?[\s-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d-]+)$
Clean the extracted NSN of all spaces and punctuation.
Finally, you can now check the NSN part in more detail.
Check that the NSN begins ^(1[1-9]|2[03489]|7([457-9]|624)) if you want to restrict the input to landlines (01, 02) and mobile numbers (074, 075, 07624, 077, 078, 079).
Consider also allowing 03 numbers as these are always charged at the same rate as 01 and 02 numbers: ^(1[1-9]|2[03489]|3[0347]|7([457-9]|624))
You can make much more detailed checks here if you want. You can even discover the number type by the initial digits.
This part is much simpler to program now that the dial prefix, country code, trunk prefix and any puncuation clutter has been dumped.
There's a very full list of patterns at:
www.aa-asterisk.org.uk/index.php/Regular...GB_Telephone_Numbers