【问题标题】:Regex working wrong, matching unexpected things正则表达式工作错误,匹配意想不到的东西
【发布时间】:2014-09-30 19:56:45
【问题描述】:

我有这个正则表达式:

[\(\+\[]?[0-9]([\-\)\.\/-\]]?\s?\(?[0-9\s\)]){8,20}?

它必须只匹配电话号码,但它也匹配以下内容:

[95.86.22.137]
95.86.22.137
(192.168.1.94)
274.1363525390625px;">
2014-8-720:32:45

有人可以帮我纠正这个正则表达式吗?

【问题讨论】:

  • 你可以使用regex101来调试它
  • 我已经花了半天的时间,但我无法做到完美
  • 首先定义phone number 的确切含义,包括它应该包含什么和不应该包含什么
  • 看这里,可能会有所帮助:stackoverflow.com/questions/16699007/…
  • 也许您应该描述一下您来自哪里的电话号码是如何形成的。

标签: python regex


【解决方案1】:

如果您真的想正确地做到这一点,我会重新开始并首先建立您打算匹配的模式,这在您的正则表达式中并不明显,也不在您的问题中 - 只有您不想要的。您需要将其视为“我想要什么?”,而不是“我要排除什么?”。把它当作“我想要什么?”而你所需要的将消除所有那些令人讨厌的其他可能性。

您必须首先决定您将接受什么作为“有效电话号码”。请记住,即使在 NANP(北美编号计划)中,也有几种不同的格式,例如:

  • XXX-XXX-XXXX 或
  • XXX XXX-XXXX 或
  • 1-XXX-XXX-XXXX 或
  • (XXX) XXX-XXXX 或
  • +(XXX) XXX-XXXX 或
  • 1 (XXX) XXX-XXXX

所有这些都是有效数字,因此您必须决定接受的格式。然后在世界其他地方有不同的格式,长度从 9(葡萄牙)到 13(韩国)数字,包括国家和国际代码。所以你必须决定:

  • 您会只接受 NANP 号码,还是接受该标准之外的其他号码?
  • 你会接受“+”还是让他们写国际代码?如果您需要代码,您的用户将输入的国家/地区的代码是否有固定位数?如果他们输入代码,您的正则表达式是否能够处理(如果可接受)或警告(如果不可接受)?
  • 您会在区号周围强制使用括号,直接允许它们(使括号可选),还是直接拒绝它们?

关于最后一个,请注意不同国家/地区的号码在不同位置有括号,即墨西哥有 2 位数的区号(顺便说一句,它不在 NANP 中)。

请记住,每次您做出此类需要某个角色的决定时,您都会否定其他可能的有效电话号码,除非您也允许该位置中的其他有效角色。这就是为什么没有一种万能的解决方案来解决您的问题。出于这个原因,许多人会告诉你去掉“+”、“(”、“)”、“-”,然后计算数字。但是,如果您认为 NANP 号码中的“1”是必需的,但有人不包括它(因为它在 NANP 中通常是可选的),或者当不同国家/地区的数字中位数不同时,这将失败 - 即使在他们自己的国家,比如新西兰。

有这个所谓的综合指南:A comprehensive regex for phone number validation

但我发现它非常缺乏解决诸如如何让一个人输入“+”与“1”和一个空格(对于 NANP 数字)、如何强制使用括号、连字符等问题。它为您提供了正则表达式而不是解释如何让你到达那里。因此,我的“博客”在这里寻求答案。

以下是我使用的将接受的严格 NANP 正则表达式:

  • +(XXX) XXX-XXXX
  • 1 (XXX) XXX-XXXX
  • (XXX) XXX-XXXX

它需要括号和连字符,我相信对于 NANP 数字,它提供了很大的灵活性,同时仍然符合标准。幸运的是,我不处理国际(NANP 之外)号码:

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

/^ = 匹配单词的开头;基本上只是表示表达式的开始

(\+|1\s)?组

  • 括号用于偏移组,表示里面的任何字符都是可选的,通过末尾的?,并允许里面的“或”条件(见管道字符)
  • \+ = 转义“+”,允许匹配加号(必须转义,因为它是正则表达式中的关键字符,使用反斜杠)
  • | = 管道字符,表示它应该匹配组内左侧或右侧的内容
  • 1\s = 需要数字 1 和空格字符。 [] 不需要空间 - 这对我不起作用,尽管我已经看到其他似乎表明它的帖子。是\s

[(] = 这就是您表示需要左括号的方式。

[2-9]\d{2} 组

  • [2-9] = 这是为了使表达式匹配数字 2-9。这是因为在 NANP 中,0 和 1 是区号开头(第一组 3 个号码)或电话交换机(第二组 3 个号码)中的无效号码。
  • \d{2} = 这表示允许 2 位数字,从 0 到 9。这是[0-9][0-9] 的简写。

对于 000-999 的三位数组,您只需说:\d{3}

[)] = 这就是您表示需要右括号的方式。

[\s] = 这需要一个空格。

[2-9]\d{2}-\d{4}组

  • 连字符之前的第一部分与之前相同。
  • 在这里需要设置连字符。如果你输入-?,它是可选的。
  • \d{4} = 这表示允许从 0 到 9 的 4 位数字。这是[0-9][0-9][0-9][0-9] 的简写

$/ = 表示匹配到单词的结尾;基本上只是表示表达式的结束。

希望这将帮助您建立自己的表达方式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-13
    • 1970-01-01
    • 2011-10-28
    • 2012-11-12
    • 2016-10-19
    • 2011-02-27
    • 1970-01-01
    相关资源
    最近更新 更多