这是一个用于确定IP地址是否属于C类的代码。但是每次我编译的时候,它都会显示错误。帮我改正吧。
代码:
gets stdin ip
regexp {(19[2-9]|2[0-1]\d|22[0-3])\.(0\d\d|1\d\d|2[0-5][0-5])\.(0\d\d|1\d\d|2[0-5][0-5])\.(0\d\d|1\d\d|2[0-5][0-5])} $ip d
puts "$d is a class c ip address"发布于 2020-08-13 19:04:35
用scan正确地做这件事
正则表达式确实不是用于此目的的工具,因为正则表达式并不是为解析数字范围而设计的(除非您正在编写一个低级解析器)。更好的做法是先解析成多个片段,然后再使用数字检查。
# Check that the string contains a dotted quad
if {
[scan $ip "%d.%d.%d.%d" a b c d] == 4 &&
($a >= 192 && $a <= 223) &&
($b >= 0 && $b <= 255) &&
($c >= 0 && $c <= 255) &&
($d >= 0 && $d <= 255)
} then {
puts "$ip is a class C IP address"
}建议您在解析之前使用Tcllib package中的ip::normalize,以应对实际上是合法IP地址的奇怪情况。
package require ip
# Note the simpler expression: normalizing handles the awkward cases for us
scan [ip::normalize $ip] "%d.%d.%d.%d" a b c d
if {$a >= 192 && $a <= 223} {
puts "$ip is a class C IP address"
}如果有人给了你错误的输入,你会得到一个很好的干净的错误来描述问题是什么,而不是一个奇怪的坏掉的程序。
使用正则表达式
这就是为什么Zawinski的格言存在:
有些人在遇到问题时会想:“我知道,我会使用正则表达式。”现在他们有两个问题。
对于某些问题,正则表达式是正确的解决方案。这不是其中之一!
如果您必须使用正则表达式,请尝试执行以下操作:
regexp {^(?:19[2-9]|2[0-1]\d|22[0-3])(?:\.(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])){3}$} $ip d是的,那太可怕了。这里是它的扩展形式,带有一些注释。
^ # Anchored at the start of the string!
(?: # Parse the first quad; 192..223 (NB: non-capturing group)
19[2-9]
|
2[0-1]\d
|
22[0-3]
)
(?: # And three sets of what matches the other quads
\. # Literal period
(?: # Parse a number in 0..255
\d{1,2}
|
1\d\d
|
2[0-4]\d
|
25[0-5]
)
) {3} # Here's where we ask for this three times
$ # Anchor at the end of the string之所以如此混乱,是因为要处理这些数字范围;REs根本不是一个很好的工具。
https://stackoverflow.com/questions/63393115
复制相似问题