首页 > 试题广场 >

判断输入的是否为IP地址

[编程题]判断输入的是否为IP地址
  • 热度指数:17806 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
写一个脚本统计文件nowcoder.txt中的每一行是否是正确的IP地址。
如果是正确的IP地址输出:yes
如果是错误的IP地址,且是四段号码的话输出:no,否则的话输出:error
假设nowcoder.txt内容如下:
192.168.1.1
192.168.1.0
300.0.0.0
123
你的脚本应该输出:
yes
yes
no
error
示例1

输入

192.168.1.1
192.168.1.0
300.0.0.0
123

输出

yes
yes
no
error
纯shell
while read line
    do
        arr=(${line//./ })
        if [ ${#arr[*]} -ne 4 ];then
                printf "error\n"
            else
                for ((i=0; i<${#arr[*]}; i++))
                    do
                        [ ${arr[${i}]} -gt 255 ] && printf "no\n" && break
                    done
                    [ $i == 4 ] && printf "yes\n"
        fi
    done
纯awk
awk -F "." '{
    if (NF == 4) {
        for (i=1; i<5; i++) {
            if ($i > 255 || $i < 0) {
                print("no");break
            }
        }
        if (i==5){print("yes")}
    } else {
        print("error")
    }
}'
纯awk 正则匹配版本
awk -F "." '{
    if (NF == 4) {
        if ($0 ~ /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[09][0-9]|[1-9][0-9]|[0-9])$/) {
                print("yes")
        } else {
                print("no")
        }
    } else {
        print("error")
    }
}'



发表于 2021-11-25 09:46:55 回复(2)
awk -F "." '{
    if(NF!=4) print "error";
    else {
        msg = "yes";
        for(i=1;i<=NF;i++){
            if($i<0||$i>255){
                msg = "no";
                break;
            }
        }
        print msg;
    }
}' nowcoder.txt

发表于 2021-11-26 23:35:06 回复(1)
awk -F'.' '{if(NF!=4){print "error";next}else{for(i=1;i<=4;i++){if(i==4){print "yes";next}else{if($i<0||$i>255){print "no";next}}}}}' nowcoder.txt
完全依靠awk的next功能实现,如果中途有一个字段不符合要求,都输出no,并且处理下一行;如果进入到最后一个字段,依然没有退出,只能说明,当前行的所有字段都是符合要求的,但是又不能在for中打印,不然会重复打印yes,于是在此前加上一个if识别四个字段都合法的情况
发表于 2021-11-20 19:41:45 回复(6)
awk -F "." '
{
    if(NF==4)
    {
        if (($1>0 && $1<=255) && ($2>=0 && $2<=255) && ($3>=0 && $3<=255) && ($4>=0 && $4<=255))
        {
            print("yes")
        }
        else
        {
            print("no")
        }
    }
    else{
        print("error")
    }
}
' nowcoder.txt
发表于 2022-03-15 15:17:02 回复(1)
此题关键在于正则匹配
0-255数字匹配
- 0-99匹配表达式:[1-9]?[0-9]
- 100-199匹配表达式:1[0-9]{2}
- 200-249匹配表达式:2[0-4][0-9]
- 250-255匹配表达式:25[0-4]
- 0-255 匹配表达式:[1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-4]

正确ip的匹配表达式:^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-4])\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-4])$

河边小石子题解如下:

#!/bin/bash

ip_yes='^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-4])\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-4])$'
ip_no='^([0-9]+\.){3}([0-9]+)$'
while read line;
do
    if [[ $line =~ $ip_no ]];then  #注意=~
        if [[ $line =~ $ip_yes ]];then
            echo "yes"
        else
            echo "no"
        fi
    else
        echo "error"
    fi
done<./nowcoder.txt
发表于 2022-07-17 18:11:21 回复(0)
#!/bin/bash

while IFS= read -r line || [ -n "$line" ]; do
    # 检查是否为空行
    if [ -z "$line" ]; then
        echo "error"
        continue
    fi

    # 初步检查格式:必须是 X.X.X.X 形式,且只含数字和点
    case "$line" in
        *[!0-9.]* | .* | *. | *..* | "")
            echo "error"
            continue
            ;;
    esac

    # 按 . 分割,存入数组(不使用 here-string)
    OIFS=$IFS
    IFS='.'
    set -- $line   # 使用 set -- 避免 here-string
    IFS=$OIFS

    # 必须恰好 4 段
    if [ $# -ne 4 ]; then
        echo "error"
        continue
    fi

    a=$1; b=$2; c=$3; d=$4

    # 检查每一段
    for octet in "$a" "$b" "$c" "$d"; do
        # 空段(如 192..1.1)已在前面过滤,这里再保险
        if [ -z "$octet" ]; then
            echo "no"
            continue 2
        fi

        # 检查前导零:长度>1 且首字符为0 → 非法
        if [ ${#octet} -gt 1 ] && [ "${octet:0:1}" = "0" ]; then
            echo "no"
            continue 2
        fi

        # 检查是否为数字(防止非数字,虽然前面已过滤)
        case "$octet" in
            *[!0-9]*)
                echo "no"
                continue 2
                ;;
        esac

        # 检查范围 0~255
        if [ "$octet" -lt 0 ] || [ "$octet" -gt 255 ]; then
            echo "no"
            continue 2
        fi
    done

    echo "yes"
done < nowcoder.txt

发表于 2025-11-07 16:30:32 回复(0)
awk -F. '{if(NF==4){for(i=1;i<=NF;i++){if($i<0||$i>255){print "no";next}}print "yes"}else{print "error"}}'

发表于 2025-02-26 23:56:26 回复(0)
awk '
    {
        if($0 ~ /^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/){  # 网上找的IPv4正则
            print "yes";
        }else if($0 ~ /([0-9]+\.){3}[0-9]+/){ # 数字.数字.数字.数字
            print "no";
        }else{
            print "error";
        }
    }
'

发表于 2025-01-16 22:53:36 回复(0)
4     gawk '{
    5       if( $0 ~ /^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/ ){ # 合法ip
    6         print "yes"
    7       }
    8     else if( length($0)<7 || length($0)>15 || !( $0 ~ /^(([0-9]{1,3}\.){3}[0-9]{1,3})$/ )){ # 从长度和ip的基本格式判断
    9         print "error"
   10       }
   11      else { # 满足合法ip的基本形式, 但不是合法ip
    13       print "no"
   14      }
   15     }' "$1"
发表于 2024-08-30 17:42:40 回复(0)
file="nowcoder.txt"
cat $file | awk  -F '.' '{
        if(NF != 4){
            print "error"
        }else if($1 ~ /^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$/ && $2 ~ /^(0|[1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$/){
                print "yes"
            }else {
                print "no"
            }
}'
发表于 2024-07-03 17:30:14 回复(0)
#!/bin/bash

while IFS= read -r line; do
if [[ $line =~ ^((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])$ ]]; then
echo "yes"
elif [[ $line =~ ^[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+$ ]]; then
echo "no"
else
echo "error"
fi
done

发表于 2024-07-02 16:27:44 回复(0)
awk -F '.' 'NF==4{flag=true;for(i=0;i<NF;i++){if(($i<0)||($i > 255)){flag=false;print "no";break;} if((flag == true)&&(i == NF-1)) {print "yes"};}} NF<4{print "error"}' nowcoder.txt
发表于 2024-06-30 21:44:36 回复(0)
# 提示:ip地址由四组八位二进制数字组成,每组数字范围是0~255
awk -F '.' '{if(NF==4){if(($1<=255 && $1>=0) && ($2<=255 && $2>=0) &&($3<=255 && $3 >=0) &&($4<=255 && $4>=0)) {print "yes"} else {print "no"}} else {print "error"}}' test15.txt

发表于 2024-06-07 10:43:39 回复(0)
#!/bin/bash
awk -F "." '{
  if(NF==4 && 0<=$1 && $1<=255&&
  0<=$2 && $2<=255&&
  0<=$3 && $3<=255&&
  0<=$4 && $4<=255){
    print "yes";}
else if(NF<4){print "error";}
else{print "no";}
}' nowcoder.txt
编辑于 2024-01-26 21:56:52 回复(0)
#!/bin/bash
while read line; do
	{
        #分割,将所有的.作为分隔符
		array=(${line//'.'/' '})
        #消息
		msg="yes"
        if ((${#array[@]} != 4)); then
            echo error;    
			continue;
		fi
		for item in ${array[@]}; do
			{
                if (( !(0<=item && item<=255) ));then
                    msg="no"
                    break;
                fi
			}
		done
        echo $msg
	}
done

发表于 2023-10-27 15:05:11 回复(0)
方法一:
#!/bin/bash
#ip地址由四组八位二进制数字组成,每组数字范围是0~255
#方法1:使用awk加循环判断:分情况讨论,列数不为4输出error;列数为4四组数都在0~255之间输出yes,否则输出no
cat nowcoder.txt | awk -F "." '{
    if(NF == 4){
        for(i = 1;i <= 4;i++){
            if($i < 0 || $i > 255){
                print "no";
                break;
            }
        }

        if(i == 5) print "yes";
    }else{
        print "error";
    }
}'

方法二:
#!/bin/bash

#方法2:awk加0~255的正则表达式直接进行模式匹配
:<<EOF
1.合理的ip地址划分为:0-9 10-99 100-199 200-249 250-255,原则是尽量多的用[0-9]进行划分,比如200-249 
2.不合理的正则表达式是在判断ip地址是否是合理的ip地址后进行判断的,所以此时在 任意个0-任意个9(至少有一个数字)的
数据范围内的所有非0-255的数字都是非合理ip。说白了只要这个填数的位置有数就行不管是多少,而我们上一步剔除了合理ip的
数据,所以剩下有数的情况就是不合理的ip地址
EOF
cat nowcoder.txt | awk '{
    if($0 ~/^(([0-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/){
        print "yes";
    }else if($0 ~/^([0-9]+\.){3}[0-9]+$/){print "no";}
    else{print "error";}
}'

方法三:
#!/bin/bash

#方法3:while按行读入处理 + awk加0~255的正则表达式直接进行模式匹配
:<<EOF
注意几个点:1.定义ip的正则表达式时用单引号括起来,防止取变量值时把它解析成字符串,它类似于一个正则命令
2.正则表达式里的{3}只对它前一个字符或者前一个括号里面的所有字符重复三次,不是从开头开始重复
3.=~表示正则匹配与字符串的是否相等的判断
4.[]]可用于正则表达式的模式匹配,而[]没有这个功能
EOF

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

while read line
do
    if [[ $line =~ ^([0-9]+\.){3}[0-9]+$ ]]
    then
        if [[ $line =~ $ip ]] #[[]]可用于正则表达式的模式匹配,而[]没有这个功能
        then
            echo yes
        else
            echo no
        fi
    else
        echo error
    fi
done < nowcoder.txt


发表于 2023-10-13 13:33:38 回复(0)
hm1头像 hm1
#!/bin/bash
for i in `cat nowcoder.txt`
do
    a=()
    IFS=$"."
    for z in $i
    do
       a+=($z)
    done
    if [ ${#a[*]} -eq 4 ]
        then
        c=0
        for i in ${a[*]}
            do
                if [ $i -lt 256 ]
                    then
                    let c++
                    fi
            done
        if [ $c -eq 4 ]
            then
                echo yes
        else
            echo no
            fi
        else
            echo error
        fi
   
    IFS=$"\n"
done

感觉写的有点复杂了,没思路啊
发表于 2023-10-11 11:11:50 回复(0)
awk -F. '{
    if(NF!=4){
        print "error"
    }
    else{
        flg = 0;
        for(i=1;i<NF;i++){
            if($i <0 || $i >255)
            {
                flg=1
                break;
            }
        }
        if(flg==1){
            print "no"
        }else{
            print "yes"
        }
    }
}' nowcoder.txt
发表于 2023-06-25 13:15:48 回复(0)
cat ip.txt | while read line;do echo $line | awk -F. '{if(NF==4 && $1<=255 ){print "yes"} else if(NF==4 && $1>255){print "no"} else{print "error"} }';done

发表于 2023-06-23 21:22:26 回复(0)
#!/bin/bash

# 方法1: 使用while read line
while read -r ip; do
    # 将Ip地址转为列表
    OLD_IFS=${IFS} # 将IFS保存到一个变量中
    IFS="."        # 将IFS赋值为新的值
    ip_list=($ip)  # 分割
    IFS=${OLD_IFS} # 将IFS还原

    column_number=${#ip_list[@]}
    # 如果不等于4,则表明这个ip是error
    if [[ ! ${column_number} -eq 4 ]]; then
        echo "error"
        continue
    fi
    # 判断ip地址是否正确,判断的标准是,第一位必须是大于1且小于等于255, 其他2~3位则必须是0~255之间

    # 遍历数组
    status="yes"
    # shellcheck disable=SC2068
    for i in ${!ip_list[@]}; do
        # 如果是第一位的话,则应该大于等于1小于255,否则则打印no,并break
        # shellcheck disable=SC2235
        if [[ $i -eq 0 ]] && ([[ ${ip_list[i]} -lt 1 ]] || [[ ${ip_list[i]} -gt 255 ]]); then
            status="no"
            break
        fi

        # 如果是非第一位的话,则应该大于等于0且小于等于255, 否则打印no,并break
        # shellcheck disable=SC2235
        if [[ ! $i -eq 0 ]] && ([[ ${ip_list[i]} -lt 0 ]] || [[ ${ip_list[i]} -gt 255 ]]); then
            status="no"
            break
        fi
    done
    echo ${status}
done <nowcoder.txt

发表于 2023-03-20 10:17:15 回复(1)