我想为一个标准的美国类型的电话号码,支持以下格式写一个正则表达式:

###-###-####
(###) ###-####
### ### ####
###.###.####

其中#表示任意数字。到目前为止,我想出了以下表达方式

^[1-9]\d{2}-\d{3}-\d{4}
^\(\d{3}\)\s\d{3}-\d{4}
^[1-9]\d{2}\s\d{3}\s\d{4}
^[1-9]\d{2}\.\d{3}\.\d{4}

分别。我不太确定最后一条是否正确。我还想知道是否有任何方式,我可以写一个单一的表达式,而不是4个不同的迎合我提到的不同格式。如果是这样,我不知道该怎么做。以及我如何修改表达式/表达式,以便我也可以包括一个条件,以支持区号作为可选组件。类似的

+1 ### ### ####

其中+1是区号,是可选的。


这个怎么样?

^(\+?[01])?[-.\s]?\(?[1-9]\d{2}\)?[-.\s]?\d{3}[-.\s]?\d{4}

编辑:我忘记了()。 编辑2:把前三位数字弄错了。


1、3和4的表达式非常相似,所以你可以使用:

^([1-9]\d{2})([- .])(\d{3})$2(\d{4})$

请注意,根据所使用的正则表达式的语言和品牌,您可能需要输入\2而不是$2,否则这种匹配可能根本不受支持。

我认为没有好办法将其与格式2结合起来,除了明显的^(regex for 1,3,4|regex for 2)$,这是丑陋的,笨拙的,并且很难取出数字的部分。

关于区号,你可以加(\+\d)?到开头捕捉一个个位数的区号(对不起,我不知道你区号的格式)。


^(\+1)?\s?(\([1-9]\d{2}\)|[1-9]\d{2})(-|\s|.)\d{3}(-|\s|.)\d{4}

^(\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}$

匹配以下内容

123-456-7890
(123) 456-7890
123 456 7890
123.456.7890
+91 (123) 456-7890

如果你不想匹配非美国号码使用

^(\+0?1\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}$

更新: 正如下面用户Simon Weaver所注意到的,如果你也对未格式化的数字感兴趣,只需将分隔符类设置为可选的[\s.-]?

^(\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}$

这个问题有很多可能的变化。这是一个正则表达式,类似于我之前放在SO上的答案。

^\s*(?:\+?(\d{1,3}))?[-. (]*(\d{3})[-. )]*(\d{3})[-. ]*(\d{4})(?: *x(\d+))?\s*$

它将匹配以下示例和更多:

18005551234
1 800 555 1234
+1 800 555-1234
+86 800 555 1234
1-800-555-1234
1 (800) 555-1234
(800)555-1234
(800) 555-1234
(800)5551234
800-555-1234
800.555.1234
800 555 1234x5678
8005551234 x5678
1    800    555-1234
1----800----555-1234

无论电话号码的输入方式如何,都可以使用捕获组来分解电话号码,以便在代码中处理它。

第一组:国家代码(例如:1或86) 第二组:地区号码(例如:800) 分组3:Exchange(例如:555) 组四:用户号码(例如:1234) 组5:分机(例如:5678)

如果你感兴趣的话,下面是这个表达的分类:

^\s*                #Line start, match any whitespaces at the beginning if any.
(?:\+?(\d{1,3}))?   #GROUP 1: The country code. Optional.
[-. (]*             #Allow certain non numeric characters that may appear between the Country Code and the Area Code.
(\d{3})             #GROUP 2: The Area Code. Required.
[-. )]*             #Allow certain non numeric characters that may appear between the Area Code and the Exchange number.
(\d{3})             #GROUP 3: The Exchange number. Required.
[-. ]*              #Allow certain non numeric characters that may appear between the Exchange number and the Subscriber number.
(\d{4})             #Group 4: The Subscriber Number. Required.
(?: *x(\d+))?       #Group 5: The Extension number. Optional.
\s*$                #Match any ending whitespaces if any and the end of string.

要使区号可选,只需在区号(\d{3})后面添加一个问号。


这是我创建的一个相当紧凑的模型。

Search: \+?1?\s*\(?-*\.*(\d{3})\)?\.*-*\s*(\d{3})\.*-*\s*(\d{4})$

Replace: +1 \($1\) $2-$3

根据以下用例进行测试。

18001234567
1 800 123 4567
1-800-123-4567
+18001234567
+1 800 123 4567
+1 (800) 123 4567
1(800)1234567
+1800 1234567
1.8001234567
1.800.123.4567
1--800--123--4567
+1 (800) 123-4567

巴基斯坦用户试试这个。这是我创建的一个相当紧凑的。

((\+92)|0)[.\- ]?[0-9][.\- ]?[0-9][.\- ]?[0-9]

根据以下用例进行测试。

+92 -345 -123 -4567
+92 333 123 4567
+92 300 123 4567
+92 321 123 -4567
+92 345 - 540 - 5883

从@Ravi的回答开始,我还为NPA(地区)代码应用了一些验证规则。

特别是:

它应该以2(或更高)开头 第二和第三位数字不能是“11”(N11)。

还有一些其他限制,包括保留块(N9X, 37X, 96X)和555,但我省略了这些,特别是因为保留块将来可能会用到,而555对于测试很有用。

这是我想到的:

^((\+\d{1,2}|1)[\s.-]?)?\(?[2-9](?!11)\d{2}\)?[\s.-]?\d{3}[\s.-]?\d{4}$

或者,如果你也想匹配空白值(如果该字段不是必需的),你可以使用:

(^((\+\d{1,2}|1)[\s.-]?)?\(?[2-9](?!11)\d{2}\)?[\s.-]?\d{3}[\s.-]?\d{4}$|^$)

我对有效数字的测试用例(许多来自@Francis的答案)是:

18005551234
1 800 555 1234
+1 800 555-1234
+86 800 555 1234
1-800-555-1234
1.800.555.1234
+1.800.555.1234
1 (800) 555-1234
(800)555-1234
(800) 555-1234
(800)5551234
800-555-1234
800.555.1234

我的无效测试用例包括:

(003) 555-1212     // Area code starts with 0
(103) 555-1212     // Area code starts with 1
(911) 555-1212     // Area code ends with 11
180055512345       // Too many digits
1 800 5555 1234    // Prefix code too long
+1 800 555x1234    // Invalid delimiter
+867 800 555 1234  // Country code too long
1-800-555-1234p    // Invalid character
1 (800)  555-1234  // Too many spaces
800x555x1234       // Invalid delimiter
86 800 555 1212    // Non-NA country code doesn't have +

我的正则表达式不包括分组来提取数字组,但可以修改它以包括这些数字组。


这是一个更全面的版本,它将尽可能多地匹配我能想到的,以及为您提供国家、地区、第一个和最后一个组匹配。

(?<number>(\+?(?<country>(\d{1,3}))(\s|-|\.)?)?(\(?(?<region>(\d{3}))\)?(\s|-|\.)?)((?<first>(\d{3}))(\s|-|\.)?)((?<last>(\d{4}))))

在jsfiddle上使用上述解决方案添加一个示例。 我根据客户的要求修改了代码。希望这也能帮助到一些人。

/^\s*(?:\+?(\d{1,3}))?[- (]*(\d{3})[- )]*(\d{3})[- ]*(\d{4})(?: *[x/#]{1}(\d+))?\s*$/

请看这里的例子


也许这是最简单的方法。

\(?\d+\)?[-.\s]?\d+[-.\s]?\d+

匹配如下:

(555) 444-6789 The 555-444-6789 555.444.6789 555 444 6789


用“+”分隔多个数字,然后用“;”"," -"或" "字符?


这个代码将匹配一个美国或加拿大的电话号码,并将确保它是一个有效的区号和交换:

^((\+1)?[\s-]?)?\(?[2-9]\d\d\)?[\s-]?[2-9]\d\d[\s-]?\d\d\d\d

在Regex101.com上测试


Regex模式来验证常规的10位电话号码加上可选的国际代码(1到3位)和可选的分机号码(任何位数):

/(\+\d{1,3}\s?)?((\(\d{3}\)\s?)|(\d{3})(\s|-?))(\d{3}(\s|-?))(\d{4})(\s?(([E|e]xt[:|.|]?)|x|X)(\s?\d+))?/g

演示:https://www.regextester.com/103299

有效的条目:

/* Full number */
+999 (999) 999-9999 Ext. 99999

/* Regular local phone number (XXX) XXX-XXXX */
1231231231
123-1231231
123123-1231
123-123 1231
123 123-1231
123-123-1231
(123)123-1231
(123)123 1231
(123) 123-1231
(123) 123 1231

/* International codes +XXX (XXX) XXX-XXXX */
+99 1234567890
+991234567890

/* Extensions (XXX) XXX-XXXX Ext. XXX... */
1234567890 Ext 1123123
1234567890Ext 1123123
1234567890 Ext1123123
1234567890Ext1123123

1234567890 Ext: 1123123
1234567890Ext: 1123123
1234567890 Ext:1123123
1234567890Ext:1123123

1234567890 Ext. 1123123
1234567890Ext. 1123123
1234567890 Ext.1123123
1234567890Ext.1123123

1234567890 ext 1123123
1234567890ext 1123123
1234567890 ext1123123
1234567890ext1123123

1234567890 ext: 1123123
1234567890ext: 1123123
1234567890 ext:1123123
1234567890ext:1123123

1234567890 X 1123123
1234567890X1123123
1234567890X 1123123
1234567890 X1123123
1234567890 x 1123123
1234567890x1123123
1234567890 x1123123
1234567890x 1123123

最后我得到了

(1,3))?(铝* (\ \ d那三)?黑——。)铝* (\ \ d那三)黑-。铝* (\ \ d那4,5)(?: * x (\ \ d +)) ?’; const phoneRegex = new RegExp('\\s*' + regexBase + '\\s*', 'g');

这是为了允许像荷兰数字这样的东西

+358 300 20200


我使用的电话号码正则表达式: / ^ [+] ? (\ d {1,2}) ? [\ s -] ? \ (\ d {3} \) ? [\ s -] ? \ d {3} [\ s -) ?\ d{4} /美元

封面:

18001234567 1 800 123 4567 Plus 1 800 123-4567 +86 800 123 4567 800-123-4567 1 (800) 123-4567 (800)123-4567 (800) 123-4567 (800)1234567 The 800-123-4567 800.123.4567


我发现这个正则表达式对于10位数的联系电话最有用:

^(?:(?:\+|0{0,2})91(\s*[\-]\s*)?|[0]?)?[789]\d{9}$

参考:https://regex101.com/r/QeQewP/1

解释:


^ (+ \ d {12} \ s 1) ? ? - ?。? \ \ (s ? d {3} \) [\ s . -] ? d {3} [\ s . -] ?\ d{4}美元

匹配这些电话号码:

1-718-444-1122
718-444-1122
(718)-444-1122
17184441122
7184441122
718.444.1122
1718.444.1122
1-123-456-7890
1 123-456-7890
1 (123) 456-7890
1 123 456 7890
1.123.456.7890
+91 (123) 456-7890
18005551234
1 800 555 1234
+1 800 555-1234
+86 800 555 1234
1-800-555-1234
1 (800) 555-1234
(800)555-1234
(800) 555-1234
(800)5551234
800-555-1234
800.555.1234
18001234567
1 800 123 4567
1-800-123-4567
+18001234567
+1 800 123 4567
+1 (800) 123 4567
1(800)1234567
+1800 1234567
1.8001234567
1.800.123.4567
+1 (800) 123-4567
18001234567
1 800 123 4567
+1 800 123-4567
+86 800 123 4567
1-800-123-4567
1 (800) 123-4567
(800)123-4567
(800) 123-4567
(800)1234567
800-123-4567
800.123.4567
1231231231
123-1231231
123123-1231
123-123 1231
123 123-1231
123-123-1231
(123)123-1231
(123)123 1231
(123) 123-1231
(123) 123 1231
+99 1234567890
+991234567890
(555) 444-6789
555-444-6789
555.444.6789
555 444 6789
18005551234
1 800 555 1234
+1 800 555-1234
+86 800 555 1234
1-800-555-1234
1.800.555.1234
+1.800.555.1234
1 (800) 555-1234
(800)555-1234
(800) 555-1234
(800)5551234
800-555-1234
800.555.1234
(003) 555-1212
(103) 555-1212
(911) 555-1212
18005551234
1 800 555 1234
+86 800-555-1234
1 (800) 555-1234

参见regex101.com


以上regex是@Francis Gagnon的轻微修改。

目的:检测任何可能的模式,用户可以分享他们的美国电话号码


版本1:

^\s*(?:\+?(\d{1,3}))?[\W\D\s]*(\d[\W\D\s]*?\d[\D\W\s]*?\d)[\W\D\s]*(\d[\W\D\s]*?\d[\D\W\s]*?\d)[\W\D\s]*(\d[\W\D\s]*?\d[\D\W\s]*?\d[\W\D\s]*?\d)(?: *x(\d+))?\s*$

在这里测试Codepen: https://codepen.io/kiranbhattarai/pen/NWKMXQO regex的解释:https://regexr.com/4kt5j


版本2:

\s*(?:\+?(\d{1,3}))?[\W\D\s]^|()*(\d[\W\D\s]*?\d[\D\W\s]*?\d)[\W\D\s]*(\d[\W\D\s]*?\d[\D\W\s]*?\d)[\W\D\s]*(\d[\W\D\s]*?\d[\D\W\s]*?\d[\W\D\s]*?\d)(?: *x(\d+))?\s*$

内容:测试用例可以是字符串的一部分。在版本1中,测试用例应该是一行工作的开始。

Codepen: https://codepen.io/kiranbhattarai/pen/GRKGNGG regex的解释:https://regexr.com/4kt9n


如果你能找到一个模式,可以失败,请做评论,我会修复它。

测试用例:通过

8 0   0  4  4  4  5   55 5
1 800 555 1234
+1 800 555-1234
+86 800 555 1234
1-800-555-1234
1 (800) 555-1234
(800)555-1234
(800) 555-1234
(800)5551234
800-555-1234
800.555.1234
800 555 1234x5678
8005551234 x5678
1    800    555-1234
1----800----555-1234
800 (555) 1234
800(555)1234
8 0 0 5 5 5 1 2 3 4
8.0.0.5.5.5.1.2.3.4
8-0-0-5-5-5-1-2-3-4
(8)005551234
(80)05551234
8(00)5551234
8@0@0@5551234
8/0/0/5/5/5/1/2/3/4
8*0*0*5*5*5*1*2*3*4
8:0:0:5:5:5:1:2:3:4
8,0,0,5,5,5,1,2,3,4
800,555,1234
800:555:1234
1-718-444-1122
718-444-1122
(718)-444-1122
17184441122
7184441122
718.444.1122
1718.444.1122
1-123-456-7890
1 123-456-7890
1 (123) 456-7890
1 123 456 7890
1.123.456.7890
+91 (123) 456-7890
18005551234
1 800 555 1234
+1 800 555-1234
+86 800 555 1234
1-800-555-1234
1 (800) 555-1234
(800)555-1234
(800) 555-1234
(800)5551234
800-555-1234
800.555.1234
18001234567
1 800 123 4567
1-800-123-4567
+18001234567
+1 800 123 4567
+1 (800) 123 4567
1(800)1234567
+1800 1234567
1.8001234567
1.800.123.4567
+1 (800) 123-4567
18001234567
1 800 123 4567
+1 800 123-4567
+86 800 123 4567
1-800-123-4567
1 (800) 123-4567
(800)123-4567
(800) 123-4567
(800)1234567
800-123-4567
800.123.4567
1231231231
123-1231231
123123-1231
123-123 1231
123 123-1231
123-123-1231
(123)123-1231
(123) 123-1231
(123) 123 1231
+99 1234567890
+991234567890
(555) 444-6789
555-444-6789
555.444.6789
555 444 6789
1 800 555 1234
+1 800 555-1234
+86 800 555 1234
1-800-555-1234
1.800.555.1234
+1.800.555.1234
1 (800) 555-1234
(800)555-1234
(800) 555-1234
(800)5551234
800-555-1234
800.555.1234
(003) 555-1212
(103) 555-1212
(911) 555-1212
18005551234
1 800 555 1234
+86 800-555-1234
1 (800) 555-1234

我只是把这个答案扔在那里,因为它解决了我的一个问题,它是基于@stormy的答案,但包括3位数的国家代码,更重要的是可以在字符串中的任何地方使用,但不会匹配的是,它的前面没有空格/字符串的开始,结尾是一个词的边界。这很有用,这样它就不会匹配URL或其他东西中间的随机数

((?:\s|^)(?:\+\d{1,3}\s?)?1?\-?\.?\s?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4})(?:\b)

这是一个正则表达式,它既能匹配北美地区的数字,也能匹配中东地区的国际数字。

^((\+|0{0,2})([0-9]){1,3})?[-.●\s]?\(?([0-9]{2,3})\)?[-.●\s]?([0-9]{3})[-.●\s]?([0-9]{4})$


这是我在FreeCodeCamp电话号码挑战中处理美国号码的正则表达式:

/^\d{3}(-|\s)\d{3}(-|\s)\d{4}$|^\d{10}$|^1\s\d{3}(-|\s)\d{3}(-|\s)\d{4}$|^(1\s?)?\(\d{3}\)(\s|\-)?\d{3}\-\d{4}$/

匹配:

555-555-5555

(555)555-5555

(555) 555-5555

555 555 5555

5555555555

1 555 555 5555 etc

我知道这不能直接回答OP的问题,但如果您问的是与OP相同的问题,那么很有可能您正在寻找一种方法来验证和存储电话号码在状态或数据库中。与其试图检测每个可能是电话号码的字符组合,不如将此任务分解为多个步骤。

去掉所有的无数字 去掉前导1s 请确保号码不超过10位

Javascript伪例子,假设"phone"是用户输入存储为字符串:

phone.replace(/\D/g, "") 
phone.replace(/^1+/g, "") 
phone.slice(0, 10) 
phone.length === 10 ? "do something" : "don't do something"

上面的代码将需要根据您的目的进行调整,并为非javascript读者保留尽可能简单的代码。

为了表示的目的,你可以总是层破折号和领先的1,但为了存储,你应该只保留实际的数字。这种方法还有一个额外的优点,就是留给您一些易于理解的正则表达式。