当我完成 regex101 测验/课程时,我应该匹配一个 IP 地址(没有前导零)。
现在以下
^[^0]+[0-9]+\\.[^0]+[0-9]+\\.[^0]+[0-9]+\\.[^0]+[0-9]+$
火柴23.34.7433.33
但无法匹配 1.2.3.4 等单个数字
为什么会这样,当我+
的应该匹配“1 到无限”次时......?
当我完成 regex101 测验/课程时,我应该匹配一个 IP 地址(没有前导零)。
现在以下
^[^0]+[0-9]+\\.[^0]+[0-9]+\\.[^0]+[0-9]+\\.[^0]+[0-9]+$
火柴23.34.7433.33
但无法匹配 1.2.3.4 等单个数字
为什么会这样,当我+
的应该匹配“1 到无限”次时......?
实际上,您为 IP 地址中的每个数字匹配超过 2 位数字,因为您有:
[^0]+[0-9]+
[^0]+
至少匹配一个字符,并且[0-9]+
至少匹配一个字符。两者都将匹配“至少 2 个字符”(字符在字符类的范围内)。
由于我上面提到的原因,也23.34.7433.3
与您的正则表达式不匹配。
您可能会出于您所说的目的尝试此正则表达式:
^(?:[1-9][0-9]{0,2}\.){3}[1-9][0-9]{0,2}$
[1-9][0-9]{0,2}
将匹配最多 3 位数字,不带前导0
.
编辑:您在评论中提到0.0.0.0
(个位零)也将被接受。上面修改后的正则表达式将是:
^(?:(?:[1-9][0-9]{0,2}|0)\.){3}(?:[1-9][0-9]{0,2}|0)$
[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]*$
清理它。
^(?:[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)$
假设您要检查 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 的数字。
图案细节:
目标是描述允许的内容:
如果我将这些规则一一添加,我将获得
2(?>[0-4][0-9]|5[0-5])
2(?>[0-4][0-9]|5[0-5]) | 1[0-9]{2}
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] | [0-9]
现在我有一个允许数字的定义。我可以减少一点模式的大小替换[1-9][0-9] | [0-9]
为[1-9]?[0-9]
然后你只需要添加点重复子模式四次:xxxx
但由于只有三个点,我写了第一个数字,然后重复 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 的任何其他内容,我为字符串的开头和字符串 ^
的结尾添加了锚点$
,然后字符串以 IP 开头和结尾。
要减小模式的大小,您可以定义一个命名组,该组允许重用它包含的子模式,
然后你可以像这样重写模式:
^
(?<nb> 2(?>[0-4][0-9]|5[0-5])|1[0-9]{2}|[1-9]?[0-9] ) # named group definition
(?> \. \g<nb> ){3} # \g<nb> is the reference to the subpattern named nb
$
您的正则表达式将匹配ABCDEFG999.FOOBSR888
等,因为[^0]
是除零以外的任何字符,并且+
.
我想你想要这个:
^[1-9]\d*(\\.[1-9]\d*){3}$
用它们的等价物替换了各种冗长的表达式,这是 4 组数字,每组都以非零开头。
实际上问题要复杂得多,因为您的方法(一旦更正)允许999.999.999.999
,这不是有效的IP。
要匹配 IP 地址,您应该使用以下模式: \b(?:\d{1,3}.){3}\d{1,3}\b
这可能是因为您需要在两个点“。”之间至少有两个数字。
尝试使用这种模式:^[^0]+[0-9]*\.[^0]+[0-9]*\.[^0]+[0-9]*\.[^0]+[0-9]*$