国际,通用和RF3966电话号码验证的正则表达式改进?

时间:2017-11-30 07:37:23

标签: regex validation internationalization phone-number tel

上下文

嗨,早些时候我正在浏览网页,以便在一个正则表达式中找到关于电话号码验证的快速回答:对于紧急,短期,国际,法国,西班牙和北美的数字(正常) ,花哨和扩展版本。)

奇怪的是,我找不到比#34; A comprehensive regex for phone number formula&#34;,因为它似乎是最好的话题,或者我错过了,这是完全可能的。< / p>

所以我是这个网站的新手并且实际上写了这个第一个问题(是的!),因为其他线程目前处于某种状态:似乎作者没有得到他和我的内容正在寻找。

这至少让我们三个人想要一个好的解决方案,因为我至少知道我的伙伴,那个第一个问我如何找到一个用于简单集成的人,比如Google Forms。

因此我当前的问题和自己的答案开始,因为我花了一些时间来建立我自己的基于建议和测试模式从另一个线程的最佳回复。如果您对该主题感兴趣,可以使用一些有趣的元素。

问题

优化和改进此正则表达式的最佳方法(无需借助编码),专门用于验证国际和大多数国家/地区的电话号码(根据RFC 3966的建议至少)?

不确定我是否也可以添加相关问题(因为它仍然是为了提高正则表达式模式的有用性),所以我猜是没有害处。

这个正则表达式应该匹配(而不是)还有其他常用格式吗?

如果你可以在这里添加它们(或链接)来更新我的测试包,我会很感激。同样有用的是电话号码,绝对不应该被验证(不需要的)。

我最初的解决方案

  • regex solution
  • 上的当前Regular Expressions 101(第4版)
  • earlier version虽然是前导空格和尾随空格,但仍然匹配结果,这对于这一点来说并不那么有用(对于时间来说有点过于花哨)。
  • 撰写本文时的最新版本考虑了主题RFC 3966上的其他帖子(来自IETF标准)和关于&#34; Natural conventions for writing telephone numbers&#的维基百科文章34。

    另一个可能的副作用是隔离国家代码,区域代码和扩展代码的匹配组......并且事情在某一点上工作相对花花公子:它只有在有一些分隔符(或括号)来区分时才能正常工作那些数字组。

匹配目标

  • 紧急和短号:112911
  • 西班牙国际:+34 987 654 321
  • 法语延长+33 (0)1 23 45 67 89
  • 法国国民:01 23 45 67 89
  • 美国延长:001-(123)-456-7890 ext-4321
  • 德语(微软风格):+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:double +是拼写错误。
  • +9-123/456.7890 x12345:分机有4个号码。
  • 1-234-567-8901:在国际号码的开头缺少00+
  • 123412345678:不是一个简短的数字,而是一个正常的数字(据我所知,在9到12之间)。
  • 1234567890123:超过最大长度(因为没有国际功能)。
  • 0012312345678901:超过最大长度(国际号码)。

    Regex101.com是重写和测试正则表达式的一大优势,到目前为止,如果没有它的帮助,我无法取得进展。然而,我不是专家,所以我只能在这里抓住表面并且我需要你的帮助来改善这个

    感谢您的阅读,写这个问题非常有教育意义(但不是我每天都会做的事情,按照我的节奏非常费时),希望它能找到答案。祝你度过愉快的一天(或者晚上......;))。

1 个答案:

答案 0 :(得分:1)

在我忘记之前,这是我放在一起的the regex最新版本及其代码的帖子:

^(?=(?:\+|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页面上添加的更多内容。你甚至可以分叉它,非常有用的功能,我是一个新粉丝。 :)

代码似乎可以使用PHP(pcre),Python和Javascript(但不是Golang),它们具有不同的性能,但不是很棒,但足以达到我们的目的。

例如,我想将\h用于水平空格(而不是\t\fspace,但它与不同平台的兼容性较低。< / p>

它仍然需要很多改进,我很想知道你将要做什么来回答我们的这个小问题,但我已经度过了......这里已经是一个阳光明媚的早晨。晚安伙计。