在正则表达式中使用if和else

时间:2013-05-20 06:28:01

标签: regex

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

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

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

由于

2 个答案:

答案 0 :(得分:3)

首先,在正则表达式中,?()不是有条件的。 ?匹配它左边的字符(组)0或1次,()启动一个没有任何内容的捕获组?...没有条件我害怕:)最接近的可能是(a|b)匹配ab ...

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

^((\+\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),其中X=(\+\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}匹配任何十进制数字1,2或3次但不多于或少于

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

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

  6. 我们之前见过的
  7. (-| )?(将-(空格)匹配为零或一次。?为wht指定零或一倍。)

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

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

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

    1. 外部()是一个捕获字符串......

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

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

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

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

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

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

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

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

      3. ...继续 我们之前见过(-| )?(匹配-(空格)零次或一次。?是指定零次或一次。)

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

        我们之前见过的{p> (-| )?(匹配-(空格)零次或一次。?是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}匹配捕获组零次或一次...即电话号码不需要扩展名

        5. 最后$匹配行尾。

          希望这足以让你彻底解决这个问题:)

答案 1 :(得分: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}\)?)

\(?是可选的左括号

发生2到3次的

\d{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