为什么这与我的例子不符?

时间:2013-09-06 20:27:30

标签: regex

当我浏览regex101测验/课程时,我应该匹配一个IP地址(不带前导零)。

现在以下

^[^0]+[0-9]+\\.[^0]+[0-9]+\\.[^0]+[0-9]+\\.[^0]+[0-9]+$

匹配23.34.7433.33

但无法匹配单个数字,如1.2.3.4

为什么这样,当我的+应该匹配“1到无限”时......?

6 个答案:

答案 0 :(得分:3)

实际上,您为IP地址中的每个号码匹配的位数超过2位数,因为您有:

[^0]+[0-9]+

[^0]+匹配至少一个字符,[0-9]+匹配至少一个字符。两者都匹配'至少2个字符'(字符在字符类的范围内)。

同样23.34.7433.3 doesn't match your regex,原因如上所述。

你可以试试这个正则表达式,用于你所说的目的:

^(?:[1-9][0-9]{0,2}\.){3}[1-9][0-9]{0,2}$

[1-9][0-9]{0,2}最多可匹配3个数字,而非前导0

编辑:您在comment中提到,0.0.0.0(单位数零)也将被接受。上面修改的正则表达式是:

^(?:(?:[1-9][0-9]{0,2}|0)\.){3}(?:[1-9][0-9]{0,2}|0)$

答案 1 :(得分:2)

[0-9]+应为[0-9]*

  • *匹配0或更多。
  • +匹配1个或更多。

你已经拥有[^0]< ---这实际上是错误的,因为它也会匹配字母。

除此之外,它将匹配第一个非零的字符,然后匹配至少一个数字。

应该写成

 [1-9][0-9]*

这基本上检查了第一个字母并查看它的数字是否在1-9之间,然后是下一个数字(0 nums到无限nums)之后是0-9。

然后这将会出现。

^[1-9][0-9]*\.[1-9][0-9]*\.[1-9][0-9]*\.[1-9][0-9]*$

Regular expression visualization

Edit live on Debuggex

清理它。

^(?:[1-9][0-9]*\.){3}[1-9][0-9]*$

这应该有用......

^(?:[1-9][0-9]*\.|[0-9])(?:[1-9][0-9]*\.|[0-9])(?:[1-9][0-9]*\.|[0-9])(?:[1-9][0-9]*|[0-9])$

清理干净。

^(?:(?:[1-9][0-9]*|0)\.){3}(?:[1-9][0-9]*|0)$

答案 2 :(得分:2)

假设您要检查IPv4,我建议您使用以下模式:

^(?<nb>2(?>[0-4][0-9]|5[0-5])|1[0-9]{2}|[1-9]?[0-9])(?>\.\g<nb>){3}$

我已经定义了一个命名子模式 nb 来缩短模式,但如果您愿意,可以重写所有并替换\g<nb>

^(?>2(?>[0-4][0-9]|5[0-5])|1[0-9]{2}|[1-9]?[0-9])(?>\.(?>2(?>[0-4][0-9]|5[0-5])|1[0-9]{2}|[1-9]?[0-9])){3}$

不允许大于255的数字。

模式细节:

目标是描述允许的内容:

  1. 以3开头的数字以“2”开头,后跟[0-4]中的数字和[0-9]中的数字或5中的数字和[0-5]中的数字,因为它可能超过255。
  2. 以3开头的数字以“1”开头,后跟任意两位数。
  3. 任何以2位数字开头且不以“0”开头的数字
  4. 任意数字,包含1位数(包括零)
  5. 如果我逐一添加这些规则,我会获得

    1. 2(?>[0-4][0-9]|5[0-5])
    2. 2(?>[0-4][0-9]|5[0-5]) | 1[0-9]{2}
    3. 2(?>[0-4][0-9]|5[0-5]) | 1[0-9]{2} | [1-9][0-9]
    4. 2(?>[0-4][0-9]|5[0-5]) | 1[0-9]{2} | [1-9][0-9] | [0-9]
    5. 现在我有一个允许数字的定义。我可以通过[1-9][0-9] | [0-9]

      将图案的大小缩小一点,以替换[1-9]?[0-9]

      然后你只需要重复四次重复子模式:x.x.x.x

      但由于只有三个点,我写第一个数字,然后我重复3次包含点和数字的组:

      2(?>[0-4][0-9]|5[0-5])|1[0-9]{2}|[1-9]?[0-9]  # the first number
      (?>\.2(?>[0-4][0-9]|5[0-5])|1[0-9]{2}|[1-9]?[0-9]){3} # the group repeated 3 times
      

      为了确保字符串不包含我描述的IP的任何其他内容,我为字符串 ^和字符串{{1}的末尾添加了锚点然后字符串以IP开头和结尾。

      要减小模式的大小,您可以定义一个允许重用其包含的子模式的命名组,

      然后你可以像这样重写模式:

      $

答案 3 :(得分:1)

你的正则表达式匹配ABCDEFG999.FOOBSR888等,因为[^0]是零以外的任何字符,+需要bith字符类。

我想你想要这个:

^[1-9]\d*(\\.[1-9]\d*){3}$

用等价物替换了各种冗长的表达式,这是4组数字,每组都以非零开头。

实际上问题要复杂得多,因为您的方法(一旦更正)允许999.999.999.999,这不是有效的IP。

答案 4 :(得分:0)

可能是因为你需要在两个点之间至少有两位数。'

尝试使用此模式:^[^0]+[0-9]*\.[^0]+[0-9]*\.[^0]+[0-9]*\.[^0]+[0-9]*$

答案 5 :(得分:0)

要匹配IP地址,您应该使用此模式: \ b(?:\ d {1,3}。){3} \ d {1,3} \ b

取自这里: http://www.regular-expressions.info/examples.html