题解 | #字符串最后一个单词的长度#
识别有效的IP地址和掩码并进行分类统计
http://www.nowcoder.com/practice/de538edd6f7e4bc3a5689723a7435682
Java ip转32二进制 + 正则表达式
刚复习完正则表达式,突然兴起练练手
如果直接用匹配点分十进制,RegularExpression会很臃肿
regexIP = "^(2(5[0-5]|[0-4]\d)|[0-1]?\d{1,2})(\.(2(5[0-5]|[0-4]\d)|[0-1]?\d{1,2})){3}$"
于是考虑转为32位二进制再匹配会方便一些
// 将 *.*.*.* 点分十进制字符串转为 32 位二进制 static String ipToBinary(String ip) { StringBuilder sb = new StringBuilder(); for (String s : ip.split("\\.")) { int n = Integer.parseInt(s); if (n > 255) { return ""; } else { // 左移8位再或运算,得到9位,取后8位 sb.append(Integer.toBinaryString(1 << 8 | n).substring(1)); } } return sb.toString(); }
然后结合计网的知识写正则表达式,只需要用最基础的正则表达式语法即可
^:匹配开头 $:匹配结尾 ?:匹配0个或1个 *:0个或多个 +:1个或多个 [0-1]:范围内任意一个值 \d:即[0-9] {n}:"E{n}"匹配n个E,"E{m,n}"匹配m~n个E,前闭后闭 // 注意java中 \ 要转义,写 \\d
完整代码
import java.util.Scanner; public class Main { // 正则表达式 static String likeIP = "^\\d{1,3}(\\.\\d{1,3}){3}$", // 匹配点分十进制 *.*.*.* regMask = "^1+0+$", // 匹配掩码 regZ = "^0{8}[0-1]{24}$", // 匹配 0.*.*.* regL = "^01{7}[0-1]{24}$", // 匹配 127.*.*.* regA = "^0[0-1]{31}$", // include 0.*.*.* & 127.*.*.* regApriv = "^00001010[0-1]{24}$", // 匹配A类私有ip regB = "^10[0-1]{30}$", regBpriv = "^101011000001[0-1]{20}$", regC = "^110[0-1]{29}$", regCpriv = "^1100000010101000[0-1]{16}$", regD = "^1110[0-1]{28}$", regE = "^1111[0-1]{28}$"; public static void main(String[] args) { Scanner sc = new Scanner(System.in); int A = 0, B = 0, C = 0, D = 0, E = 0, ERR = 0, PRIV = 0; while (sc.hasNext()) { String[] input = sc.next().split("~"); if (input.length == 0) { break; } String ip = input[0]; String mask = input[1]; // System.out.println(ip + " " + mask); // 验证掩码 if (mask.matches(likeIP)) { if (!ipToBinary(mask).matches(regMask)) { ERR++; // System.out.println("error mask"); continue; // 掩码错误,跳过 } } // 验证ip if (ip.matches(likeIP)) { String ipStr = ipToBinary(ip); // System.out.println(ipStr); if (ipStr.matches(regZ) || ipStr.matches(regL)) { // 0.*.*.* 和 127.*.*.* 不做处理 } else { if (ipStr.matches(regA)) { A++; // System.out.println(ip + " is a A ip"); if (ipStr.matches(regApriv)) { PRIV++; } } else if (ipStr.matches(regB)) { B++; // System.out.println(ip + " is a B ip"); if (ipStr.matches(regBpriv)) { PRIV++; } } else if (ipStr.matches(regC)) { C++; // System.out.println(ip + " is a C ip"); if (ipStr.matches(regCpriv)) { PRIV++; } } else if (ipStr.matches(regD)) { D++; // System.out.println(ip + " is a D ip"); } else if (ipStr.matches(regE)) { E++; // System.out.println(ip + " is a E ip"); } } } else { ERR++; } } System.out.println(A+" "+B+" "+C+" "+D+" "+E+" "+ERR+" "+PRIV); } // 将 *.*.*.* 点分十进制字符串转为 32 位二进制 static String ipToBinary(String ip) { StringBuilder sb = new StringBuilder(); for (String s : ip.split("\\.")) { int n = Integer.parseInt(s); if (n > 255) { return ""; } else { sb.append(Integer.toBinaryString(1 << 8 | n).substring(1)); // 左移8位再或运算,得到9位,取后8位 } } return sb.toString(); } }