针对国际、常见和RF3966电话号码验证的正则表达式改进?

4

背景

你好,之前我在浏览网络以寻找有关电话号码验证的快速答案,希望能找到唯一正则表达式公式:用于紧急情况、短号码、国际、法语、西班牙语和北美洲号码(普通、花哨和扩展版本)。

奇怪的是,我找不到比 "一个完整的电话号码正则表达式公式" 更好的主题,因为它似乎是这方面最好的话题,或者可能是我错过了什么。

所以我是新来的,并且实际上正在撰写第一个问题(耶!),因为那个其他线程目前被保留了某种程度:似乎作者没明白他和我正在寻找什么。

这使得我们中至少有三个人希望有一个好的解决方案,因为我至少知道我的朋友,他首先问我是否能够在像谷歌表格这样的简单集成中使用它。

 

因此,我提出当前的问题和自己的答案,因为我花了一些时间来根据其他线程中最佳答案的建议和测试模式来构建自己的方案。如果你对这个主题感兴趣,有一些有趣的元素。

问题

如何优化和改进此正则表达式(不使用编程),该正则表达式专门用于验证国际和大多数国家的电话号码(至少符合RFC 3966的建议)?

不确定是否可以添加一个相关问题(因为仍然旨在提高正则表达式模式的实用性),但问一下也没有坏处。

还有其他常用格式应该(或不应该)匹配此正则表达式吗

如果您可以在此处添加它们(或链接),让我更新我的测试包,我将不胜感激。同样有用的是绝对不应该验证的电话号码(不需要的电话号码)。

我的初始解决方案

另一个可能的附加项是将匹配组隔离为国家代码、区号和扩展代码...当有一些分隔符(或括号)来区分这些数字组时,事情相对顺利。

匹配目标

  • 紧急短号:112911
  • 西班牙国际号码:+34 987 654 321
  • 法国扩展号码:+33 (0)1 23 45 67 89
  • 法国国内号码:01 23 45 67 89
  • 美国扩展号码:001-(123)-456-7890 ext-4321
  • 德国(Microsoft风格):+49 (1234) 567890
  • 墨西哥国内号码:(01 55) 1234 5678
  • 假设的国际号码(最大长度?):00321-(4321)-567.89 ext-4321

另一个匹配目标是有一个不会表现得太差的正则表达式,因为它不会在代码的关键部分使用。

还有,我们如何优化那些人们会找到/提出但不改变其结果的最佳正则表达式?

主线程的目标

  • +1(234)/567.8901 x1234及其变形(使用不同的分隔符:./-和水平的whitespaces)。
  • 2345678901:我猜是在美国拨打的相同号码。

不确定它应该如何工作,因为我认为在任何国际号码前都需要加上+(或其等效的双零00)...我总是这样做。另一个线程列出了没有加号的正数匹配列表。

有人能确认一下对于美国号码,+00不是必需的吗?再次感谢。

最佳的非期望格式

  • 12(34567890123)456789012345:括号不匹配。
  • )123(34567890:括号错误匹配。
  • ++34123456789:双加号是一个笔误。
  • +9-123/456.7890 x12345:扩展号码有4个数字以上。
  • 1-234-567-8901:国际号码前缺少00+
  • 123412345678:不是短号码,但也不是正常号码(我所知道的在9到12之间)。
  • 1234567890123:超过最大长度(因为没有国际功能)。
  • 0012312345678901:超过最大长度(作为国际号码)。
Regex101.com对于重写和测试正则表达式起到了很大的帮助,没有它的帮助,我不可能取得如此进展。然而,我并不是专家,所以我在这里只能浅尝辄止,我需要你的帮助来改进这个问题
感谢您的阅读,写这个问题很有教育意义(但不是我每天都会做的事情,在我的速度下非常耗时),希望它也能找到答案。祝您有一个愉快的一天(或夜晚... ;))。
1个回答

2

在我忘记之前,这里是我整理的正则表达式最新版本的帖子及其代码:

^(?=(?:\+|0{2})?(?:(?:[\(\-\)\.\/ \t\f]*\d){7,10})?(?:[\-\.\/ \t\f]?\d{2,3})(?:[\-\s]?[ext]{1,3}[\-\.\/ \t\f]?\d{1,4})?$)((?:\+|0{2})\d{0,3})?(?:[\-\.\/ \t\f]?)(\(0\d[ ]?\d{0,4}\)|\(\d{0,4}\)|\d{0,4})(?:[\-\.\/ \t\f]{0,2}\d){3,8}(?:[\-\s]?(?:x|ext)[\-\t\f ]?(\d{1,4}))?$

据我所知,它通过了我在问题中提出的测试以及我在Regex101.com页面上添加的一些测试。您甚至可以fork它,这是非常有用的功能,我是一个新粉丝。 :)
该代码似乎可以在PHP(pcre),Python和Javascript中按原样工作(但不适用于Golang),性能略有差异,但对于我们的目的来说已足够好。
例如,我想使用“\h”来表示水平空白符(而不是“\t”,“\f”和“空格”),但它与不同的平台兼容性较差。
它仍然需要许多改进,我迫不及待地想看到您将为解决我们这个小问题做出什么贡献,但我已经筋疲力尽了……这里已是一个阳光明媚的早晨。晚安大家。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接