3

我一直在努力寻找合适的解决方案:-

我需要一个匹配所有英国电话号码和手机的正则表达式。

到目前为止,这个似乎涵盖了英国的大部分数字:

^0\d{2,4}[ -]{1}[\d]{3}[\d -]{1}[\d -]{1}[\d]{1,4}$

但是,手机号码不适用于此正则表达式或写在单个实心块中的电话号码,例如 01234567890。

谁能帮我创建所需的正则表达式?

4

7 回答 7

4
  [\d -]{1}

明显不正确:数字或空格或连字符。

  01000 123456

01000 不是有效的英国区号。123456 不是有效的本地号码。

测试数据必须是实数区号和实数范围,这一点很重要。

  ^\s*(?(020[7,8]{1})?[ ]?[1-9]{1}[0-9{2}[ ]?[0-9]{4})|(0[1-8]{1}[0-9]{3})?[ ]?[1-9]{1}[0-9]{2}[ ]?[0-9]{3})\s*|[0-9]+[ ]?[0-9]+$

由于许多不同的原因,上述模式是垃圾。

[7,8] 匹配 7 或逗号或 8。您不需要匹配逗号。

伦敦数字也以 3 开头,而不仅仅是 7 或 8。

伦敦 020 号码并不是唯一的 2+8 格式号码;另见 023、024、028 和 029。

[1-9]{1} 简化为 [1-9]

[]?简化为 \s?

一次找到了初始0,为什么还要一次又一次地寻找呢?

^(0....|0....|0....|0....)$ 简化为 ^0(....|....|....|... .)$

严重地。([1]|[2]|[3]|[7]){1} 在这里简化为 [1237]。

英国电话号码使用多种格式:2+8、3+7、3+6、4+6、4+5、5+5、5+4。一些用户不知道哪种格式适用于哪个数字范围,并且可能在输入时使用了错误的格式。让他们这样做;你对数字感兴趣。

第 1 步:检查输入格式是否有效

确保输入看起来像英国电话号码。接受各种拨号前缀,+44、011 44​​、00 44,带或不带括号、连字符或空格;或带有前导 0 的国家格式。让用户对数字的其余部分使用他们想要的任何格式:(020) 3555 7788 或 00 (44) 203 555 7788 或 02035-557-788,即使它是错误的格式那个特定的数字。不要担心不平衡的括号。输入的重要部分是确保它是正确的位数。标点和空格无关紧要。

  ^\(?(?:(?:0(?:0|11)\)?[\s-]?\(?|\+)44\)?[\s-]?\(?(?:0\)?[\s-]?\(?)?|0)(?:\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}|8(?:00[\s-]?11[\s-]?11|45[\s-]?46[\s-]?4\d))(?:(?:[\s-]?(?:x|ext\.?\s?|\#)\d+)?)$

上面的模式匹配可选的左括号,后跟 00 或 011 和可选的右括号,后跟可选的空格或连字符,然后是可选的左括号。或者,最初的左括号后面是文字 +,后面没有空格或连字符。前两个选项中的任何一个都紧跟 44 和可选的右括号,然后是可选的空格或连字符,然后是可选的括号中的可选 0,然后是可选的空格或连字符,然后是可选的左括号(国际格式)。或者,该模式匹配可选的初始左括号,后跟 0 中继代码(国家格式)。

前一部分之后是 NDC(区号)和 2+8、3+7、3+6、4+6、4+5、5+5 或 5+4 格式的用户电话号码,有或没有空格和/或连字符。这还包括在用户认为区号结束和本地用户号码开始的位置之后提供可选的右括号和/或可选的空格或连字符。该模式允许任何格式与任何 GB 编号一起使用。如果用户在输入时使用了此数字的错误格式,则必须由后面的逻辑更正显示格式。

该模式以可选的分机号码结束,该号码安排为可选空格或连字符,后跟 x、分机和可选句点,或 #,后跟分机号码数字。整个模式不会费心检查平衡括号,因为这些将在下一步中从数字中删除。

在这一点上,你不在乎数字是从 01 还是 07 开始还是其他什么。您不在乎它是否是有效的区号。后面的步骤将处理这些问题。

第 2 步:提取 NSN,以便更详细地检查其长度和范围

使用上述模式检查输入看起来像 GB 电话号码后,下一步是提取 NSN 部分,以便更详细地检查其有效性,然后针对适用的号码范围以正确的方式格式化。

  ^\(?(?:(?:0(?:0|11)\)?[\s-]?\(?|\+)(44)\)?[\s-]?\(?(?:0\)?[\s-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d-]+)(?:((?:x|ext\.?\s?|\#)\d+)?)$

使用上述模式从 $1 中提取 '44' 以了解使用了国际格式,否则如果 $1 为空,则假定为国家格式。

从 $3 中提取可选的分机号码详细信息并将其存储起来以备后用。

从 $2 中提取 NSN(包括空格、连字符和括号)。

第 3 步:验证 NSN

从 $2 中删除空格、连字符和括号,并使用进一步的 RegEx 模式来检查长度和范围并识别数字类型。

这些模式会简单得多,因为它们不必处理各种拨号前缀或国家代码。

因此,匹配有效手机号码的模式很简单

  ^7([45789]\d{2}|624)\d{6}$

保费率为

  ^9[018]\d{8}$

每种号码类型将有许多其他模式:固定电话、业务费率、非地理、VoIP 等。

通过将问题分解为几个步骤,可以允许非常广泛的输入格式,并且非常详细地检查 NSN 的数字范围和长度。

第 4 步:存储号码

提取并验证 NSN 后,将号码与国家代码和所有其他数字一起存储,不带空格或标点符号,例如 442035557788。

第 5 步:格式化显示的数字

另一组简单的规则可用于在开头添加必要的 +44 或 0 来格式化数字。

以 03 开头的数字的规则是

  ^44(3\d{2})(\d{3])(\d{4})$

格式化为

  0$1 $2 $3 or as +44 $1 $2 $3

对于以 02 开头的数字是

  ^44(2\d)(\d{4})(\d{4})$ 

格式化为

  (0$1) $2 $3 or as +44 $1 $2 $3

完整的清单很长。我可以将它全部复制并粘贴到这个线程中,但是随着时间的推移,很难在多个地方维护这些信息。目前可以在以下网址找到完整列表:http: //aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers

于 2012-11-08T20:04:45.233 回答
3

考虑到人们有时会在随机的地方用空格写他们的数字,你最好一起忽略空格 - 你可以使用像这样简单的正则表达式:

^0(\d ?){10}$

这匹配:

  • 01234567890
  • 01234 234567
  • 0121 3423 456
  • 01213 423456
  • 01000 123456

但它也会匹配:

  • 01 2 3 4 5 6 7 8 9 0

所以你可能不喜欢它,但它肯定更简单。

于 2010-12-03T13:46:17.400 回答
2

去掉所有空格和非数字字符,然后进行测试。这将是 musch ,比尝试考虑括号、空格等所有可能的选项要容易得多。尝试以下操作:

@"^(([0]{1})|([\+][4]{2}))([1]|[2]|[3]|[7]){1}\d{8,9}$"

0以or开头+44(对于国际)-我相信您可以0044根据需要添加。
然后它有一个1, 2,37
然后它有 8 位或 9 位数字。

如果您想变得更聪明,以下可能是有用的参考:http ://en.wikipedia.org/wiki/Telephone_numbers_in_the_United_Kingdom

于 2010-09-08T15:56:35.743 回答
2

这个正则表达式可以吗?

//  using System.Text.RegularExpressions;

/// <summary>
///  Regular expression built for C# on: Wed, Sep 8, 2010, 06:38:28 
///  Using Expresso Version: 3.0.2766, http://www.ultrapico.com
///  
///  A description of the regular expression:
///  
///  [1]: A numbered capture group. [\+44], zero or one repetitions
///      \+44
///          Literal +
///          44
///  [2]: A numbered capture group. [\s+], zero or one repetitions
///      Whitespace, one or more repetitions
///  [3]: A numbered capture group. [\(?]
///      Literal (, zero or one repetitions
///  [area_code]: A named capture group. [(\d{1,5}|\d{4}\s+?\d{1,2})]
///      [4]: A numbered capture group. [\d{1,5}|\d{4}\s+?\d{1,2}]
///          Select from 2 alternatives
///              Any digit, between 1 and 5 repetitions
///              \d{4}\s+?\d{1,2}
///                  Any digit, exactly 4 repetitions
///                  Whitespace, one or more repetitions, as few as possible
///                  Any digit, between 1 and 2 repetitions
///  [5]: A numbered capture group. [\)?]
///      Literal ), zero or one repetitions
///  [6]: A numbered capture group. [\s+|-], zero or one repetitions
///      Select from 2 alternatives
///          Whitespace, one or more repetitions
///          -
///  [tel_no]: A named capture group. [(\d{1,4}(\s+|-)?\d{1,4}|(\d{6}))]
///      [7]: A numbered capture group. [\d{1,4}(\s+|-)?\d{1,4}|(\d{6})]
///          Select from 2 alternatives
///              \d{1,4}(\s+|-)?\d{1,4}
///                  Any digit, between 1 and 4 repetitions
///                  [8]: A numbered capture group. [\s+|-], zero or one repetitions
///                      Select from 2 alternatives
///                          Whitespace, one or more repetitions
///                          -
///                  Any digit, between 1 and 4 repetitions
///              [9]: A numbered capture group. [\d{6}]
///                  Any digit, exactly 6 repetitions
///  
///
/// </summary>
public Regex MyRegex = new Regex(
      "(\\+44)?\r\n(\\s+)?\r\n(\\(?)\r\n(?<area_code>(\\d{1,5}|\\d{4}\\s+"+
      "?\\d{1,2}))(\\)?)\r\n(\\s+|-)?\r\n(?<tel_no>\r\n(\\d{1,4}\r\n(\\s+|-"+
      ")?\\d{1,4}\r\n|(\\d{6})\r\n))",
    RegexOptions.IgnoreCase
    | RegexOptions.Singleline
    | RegexOptions.ExplicitCapture
    | RegexOptions.CultureInvariant
    | RegexOptions.IgnorePatternWhitespace
    | RegexOptions.Compiled
    );



//// Replace the matched text in the InputText using the replacement pattern
// string result = MyRegex.Replace(InputText,MyRegexReplace);

//// Split the InputText wherever the regex matches
// string[] results = MyRegex.Split(InputText);

//// Capture the first Match, if any, in the InputText
// Match m = MyRegex.Match(InputText);

//// Capture all Matches in the InputText
// MatchCollection ms = MyRegex.Matches(InputText);

//// Test to see if there is a match in the InputText
// bool IsMatch = MyRegex.IsMatch(InputText);

//// Get the names of all the named and numbered capture groups
// string[] GroupNames = MyRegex.GetGroupNames();

//// Get the numbers of all the named and numbered capture groups
// int[] GroupNumbers = MyRegex.GetGroupNumbers();

请注意空格和破折号如何是可选的,并且可以成为其中的一部分。现在它还分为两个捕获组,称为area_codetel_no将其分解并更容易提取。

于 2010-09-08T16:01:06.180 回答
0

它不是一个单一的正则表达式,但有来自Braemoor Software的示例代码,易于遵循且相当全面。

JS 版本可能是最容易阅读的。它去除了空格和连字符(我意识到你说过你不能这样做),然后应用一些正则表达式检查和负正则表达式检查。

于 2010-12-03T13:55:33.977 回答
0

首先剥离非数字,除了 + 作为第一个字符。

(Javascript)

var tel=document.getElementById("tel").value;
tel.substr(0,1).replace(/[^+0-9]/g,'')+tel.substr(1).replace(/[^0-9]/g,'')

下面的正则表达式允许在国际指示符 + 之后 7 到 15 位数字(国际电联最大值)之间的任意组合,除非代码是 +44(英国)。否则,如果字符串以 +44、+440 或 0 开头,后跟 2 或 7,然后是任意数字的 9,或者后跟 1,然后是除 0 以外的任何数字,然后是任意数字中的 7 或 8数字。(所以 0203 有效,0703 有效但 0103 无效)。目前没有 025(或伦敦 0205)这样的代码,但总有一天会分配到这些代码。

/(^\+(?!44)[0-9]{7,15}$)|(^(\+440?|0)(([27][0-9]{9}$)|(1[1-9][0-9]{7,8}$)))/

其主要目的是识别非公司号码的正确起始数字,然后是正确的数字位数。如果用户的本地号码是 5、6、7 或 8 位数字,则不推断。它没有强制禁止用户号码中的初始“1”或“0”,关于这些旧规则是否仍在执行,我找不到任何信息。英国电话规则不适用于来自英国以外的格式正确的国际电话号码。

于 2014-04-09T00:29:49.843 回答
0

经过长时间搜索有效的正则表达式以涵盖英国案例后,我发现验证英国电话号码的最佳方法(如果您使用客户端 javascript)是libphonenumber-js与自定义配置一起使用以减少捆绑包大小:

如果您使用的是 NodeJS,请运行以下命令生成 UK 元数据:

npx libphonenumber-metadata-generator metadata.custom.json --countries GB --extended

然后导入并使用元数据libphonenumber-js/core

import { isValidPhoneNumber } from "libphonenumber-js/core";
import data from "./metadata.custom.json";

isValidPhoneNumber("01234567890", "GB", data);

代码沙盒示例

于 2022-01-06T12:20:45.403 回答