0

我很难理解这个特定的正则表达式(它目前用于检查用户输入的电话号码):

^((\+\d{1,3}(-| )?\(?\d\)?(-| )?\d{1,3})|(\(?\d{2,3}\)?))(-| )?(\d{1,4})(-| )?(\d{6})(( x| ext)\d{1,5}){0,1}$

我读到“?()”用于正则表达式中的if条件,但我仍然不清楚这个正则表达式背后的逻辑以及它接受和拒绝什么样的输入。

谢谢

4

2 回答 2

3

首先,在正则表达式中,?()不是条件。?将其左侧的字符(组)匹配 0 次或 1 次,并()开始一个没有任何内容的捕获组?...没有条件我担心 :) 最接近的可能是(a|b)匹配a或匹配b...

正则表达式有点难读,所以

^((\+\d{1,3}(-| )?\(?\d\)?(-| )?\d{1,3})|(\(?\d{2,3}\)?))(-| )?(\d{1,4})(-| )?(\d{6})(( x| ext)\d{1,5}){0,1}$

试试 regexper.com,输入正则表达式,它会为您绘制一个状态图...

使用一些制表符来分解表达式:

^(
    (\+\d{1,3}(-| )?
    \(?\d\)?(-| )?
    \d{1,3})
  |(
    \(?\d{2,3}\)?
   )
)

(-| )?(\d{1,4})
(-| )?(\d{6})
(
    ( x| ext)\d{1,5}
){0,1}$

(注意使一些空格难以阅读,但我们将通过参考原文来完成)

^匹配一行的开头

下一组是((\+\d{1,3}(-| )?\(?\d\)?(-| )?\d{1,3})|(\(?\d{2,3}\)?))

这有两个部分:(X|Y)、 whereX=(\+\d{1,3}(-| )?\(?\d\)?(-| )?\d{1,3})Y=(\(?\d{2,3}\)?)。这将匹配X Y...

分解X=(\+\d{1,3}(-| )?\(?\d\)?(-| )?\d{1,3})

  1. 外面()是一个捕获,所以去掉这些......

  2. \+匹配文字加号。请注意,它必须使用转义,\因为 + 是一个元字符,意思是“匹配一个或多个前一个”。

  3. \d{1,3}匹配任何十进制数字 eiter 1、2 或 3 次,但不多也不少

  4. (-| )?匹配-(空格)零次或一次。是 wht 指定零次?或一次。

  5. \(?\d\)匹配文字 '(' (注意转义)零次或一次。然后是十进制数字,然后是另一个文字)

  6. (-| )?我们以前见过(匹配-(空格)零次或一次?。is wht 指定零次或一次。)

  7. \d{1,3}我们之前也见过(匹配任何十进制数字 eiter 1、2 或 3 次,但不多也不少)

所以我们可以说X匹配(并捕获 - 外部()正在做的事情)任何以加号开头的字符串,有 1 到 3 个数字,然后可能是空格或连字符,括号内的数字,可能是另一个空格或连字符,然后另外 1 到 3 位数。这是作为第一个捕获组捕获的……呸!

分解Y=(\(?\d{2,3}\)?)

  1. 外面()是一个捕获,所以把这些串起来......

  2. \(?匹配文字(零次或一次。

  3. \d{2,3}匹配任何数字两次或三次

  4. \)?匹配文字)零次或一次

所以我们可以说它Y匹配一个两位或三位数字,可能用括号括起来。这是作为第一个捕获组捕获的。天哪!

现在我们有了XY我们可以看到正则表达式的第一块匹配的是什么(大脑融化!)。

第一个块,称之为CHUNK1匹配并捕获

  1. 任何以加号开头的字符串,有 1 到 3 位数字,然后可能是空格或连字符,括号内的数字,可能是另一个空格或连字符,然后是另外 1 到 3 位数字

  2. 任何两位或三位数字,可能用括号括起来

继续…… (-| )?我们以前见过(匹配-(空格)零次或一次?。is wht 指定零次或一次。)

(\d{1,4})匹配长度为 1、2、3 或 4 位的数字字符串。这形成了第二个捕获组。

(-| )?我们以前见过(匹配-(空格)零次或一次?。is wht 指定零次或一次。)

(\d{6})匹配正好 6 位数字的字符串

所以在这里你匹配一个字符串,一个可能的空格或连字符,1 到 4 个数字,另一个可能的空格或连字符,然后是 6 个数字。调用这个chunk2

到目前为止,我们已经匹配了任何由以下组成的字符串,chunk1紧接着chunk2...

这结束了电话号码的主要部分,其余部分似乎处理扩展......

下一点是(( x| ext)\d{1,5}){0,1}。让我们稍微分解一下。

  1. 周围的括号是捕获组。

  2. ( x| ext)匹配两个文字字符串 'x' 或 'ext' 中的任何一个 - 注意开头的空格。

  3. \d{1,5}匹配任何数字 1、2、3、4 或 5 次。

  4. {0,1}匹配捕获组零次或一次...即电话号码不需要有分机号

最后$匹配行尾。

希望这已经很好地分解了字符串,以便您完成:)

于 2013-05-20T07:00:33.130 回答
0

只需将正则表达式分成几部分,看看它们的含义:

第一个组((\+\d{1,3}(-| )?\(?\d\)?(-| )?\d{1,3})|(\(?\d{2,3}\)?)) ,表示要么匹配这个组,要么匹配这个(\+\d{1,3}(-| )?\(?\d\)?(-| )?\d{1,3})(\(?\d{2,3}\)?)

现在采取:(\+\d{1,3}(-| )?\(?\d\)?(-| )?\d{1,3})

\+将匹配“+”字符

\d{1,3}将匹配任何出现 1 到 3 次的数字

(-| ) 将匹配 - 或之后的空间?这表示前面的标记是可选的,这意味着 (-| ) 它是可选的

\(? 将匹配可选的左括号

\d将匹配一个数字

\)?将匹配可选的右括号

(-| )?将匹配 - 或可选的空格

\d{1,3}将匹配出现 1 到 3 次的数字

现在参加这个小组:(\(?\d{2,3}\)?)

\(?是可选的开口支架

\d{2,3} 出现 2 到 3 次的数字

\)?是可选的右括号

现在采取正则表达式的后半部分:(-| )?(\d{1,4})(-| )?(\d{6})(( x| ext)\d{1,5}){0,1}

(-| )?将匹配 - 或空格(可选)

(\d{1,4})将匹配出现 1 到 4 次的数字

(-| )?将匹配 - 或空格(可选)

(\d{6})将匹配精确出现 6 次的数字

(( x| ext)\d{1,5})将匹配“x”或“ext”,然后出现 1 到 5 次数字,整个组可能出现 0 到 1 次。

可能的匹配:

(23)-1-123232
23-1-123232
2312121321214
231212131
2312121311222
123232121 x1
123232121 ext1
+1-(1)-1-1234-123456
+1-(1)-1-1234-123456 x1
+1-(1)-1-1234-123456 ext12345
于 2013-05-20T07:02:11.863 回答