【问题标题】:Decoding a regex... I know what it's function is but I want to understand exactly what is happening解码正则表达式...我知道它的功能是什么,但我想确切地了解正在发生的事情
【发布时间】:2013-07-10 02:26:50
【问题描述】:

我有一个正则表达式,我将使用它来验证输入的号码是否采用标准的美国电话格式(即 (###) ###-####)。我是正则表达式的新手,但在弄清楚每个字符的确切功能时仍然遇到了一些麻烦。如果有人会逐个阅读/验证我的理解,我将非常感激。另外,如果正则表达式是错误的,我显然很想知道。

\D*?(\d\D*?){10}

我认为正在发生的事情:
\D*?( 表示括号元字符的转义序列...不确定为什么 \D*? 是必要的
\d 表示数字
\D*?表示有一个非数字字符 (-) 后跟右括号。
{10} 表示 10 位数字

我感到非常不确定如何解释这一点,就像我对正则表达式为何按其顺序等方面的理解非常模糊。在此先感谢您的帮助/解释。

编辑

这似乎不是我想要的最好的正则表达式。另一种可能性是 [(][0-9]{3}[)] [0-9]{3}-[0-9]{4},但有人告诉我这会失败。我想我需要对正则表达式做更多的工作来解决这个问题。

【问题讨论】:

  • This 可能会有所帮助。
  • 这是满足您要求的非常广泛的正则表达式 - 它匹配各种输入 - 例如a5bcdefgh55a55c5d5g5!5q5 将匹配。简单来说,它只需要一个字符串中的 10 个数字 - 也就是说,输入可以在数字之间以及字符串的开头和结尾包含任意数量(包括 0)的随机字符。将此添加为评论,因为这里的答案确实应该是解决问题的更好方法。
  • @500-InternalServerError: 哇,debuggex 太棒了。感谢您链接到它。 OP:你可以试试这样的表达方式:debuggex.com/r/MSYZS_GBTT3UdNM9/0
  • 同意 debuggex 非常有用。我想出了 (\d{3})\d{3}[-]\d{4}$ 这似乎工作正常。

标签: regex


【解决方案1】:

\D 匹配任何非数字字符。

*表示前一个字符重复0次或多次。

*? 表示前一个字符重复 0 次或多次,但直到匹配正则表达式中的下一个字符。一开始可能有点困难,但在您的正则表达式中,下一个字符是\d,这意味着\D*? 将匹配最少数量的字符,直到下一个\d 字符。

( ... ) 是一个捕获组,也用于对事物进行分组。例如{10} 表示前一个字符或组正好重复 10 次。

现在,\D*?(\d\D*?){10} 将精确匹配 10 个数字,无论是否以非数字字符开头,数字之间的非数字字符(如果存在)。

[(][0-9]{3}[)] [0-9]{3}-[0-9]{4}

这个正则表达式要好一些,因为它不只是接受任何东西(就像第一个正则表达式一样)并且会匹配格式(###) ###-####(注意空格是正则表达式中的一个字符!)。

这里介绍的新东西是方括号。这些代表字符类。 [0-9] 表示 09 之间的任何字符,这意味着它将匹配 0、1、2、3、4、5、6、7、8 或 9。在匹配后添加 {3} 3个相似的字符类,由于这个字符类只包含数字,所以它会精确匹配3个数字。

字符类可用于转义某些字符,例如()(注意我之前提到它们用于捕获组或分组),因此[(][)] 是文字@ 987654340@ 和 ) 而不是用于捕获/分组。

您还可以使用反斜杠 (\) 来转义字符。因此:

\([0-9]{3}\) [0-9]{3}-[0-9]{4}

也可以。如果您只是想查看电话号码是否与上述格式匹配,我还建议使用线路锚点 ^$。这确保了字符串只有电话号码,没有别的。 ^ 匹配行首,$ 匹配行尾。因此,正则表达式将变为:

^\([0-9]{3}\) [0-9]{3}-[0-9]{4}$    

但是,我不知道美国不同电话号码格式的所有组合,所以如果您有不同的电话号码格式,这个正则表达式可能需要一些调整。

【讨论】:

  • +1 用于解释更好的解决方案。值得注意的是,在这种情况下,使用 [0-9] 而不是 \d 确实是一个更好的主意,因为使用后者也将允许输入:“(٣௨౮) ໙੩૪-୭༤૯௦” - 如果有人决定测试您的验证彻底... ;-) 换句话说,\d 匹配从希伯来语到中文的 任何 位 unicode 字符,而字符类只允许指定的罗马数字。
  • @JimmiTh 这就是为什么我没有将[0-9] 改回/d :) 但另一方面,我不想明确提及这一点,因为已经有很多了立即同化!
【解决方案2】:

\D 是“不是数字”; \d 是“数字”。考虑到这一点:

这匹配零个或多个非数字,然后匹配一个数字和任意数量的非数字字符 10 次。如果格式正确,这实际上不会验证数字是否正确,只是它包含 10 位数字。我怀疑正则表达式一开始就不是你想要的。

例如,以下将匹配您的正则表达式:

this is some bad text 1 and some more 2 and more 34567890

【讨论】:

    【解决方案3】:

    \D 匹配一个不是数字的字符 * 重复上一项 0 次或更多次 ?找到第一个出现 \d 匹配一个数字

    所以你的组匹配 10 位数字或非数字

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-17
      相关资源
      最近更新 更多