JavaScript 字符串:验证IP地址【思路与知识点总结】

描述
编写一个函数来验证输入的字符串是否是有效的 IPv4 或 IPv6 地址
IPv4 地址由十进制数和点来表示,每个地址包含4个十进制数,其范围为 0 - 255, 用(“.”)分割。比如,172.16.254.1;
同时,IPv4 地址内的数不会以 0 开头。比如,地址 172.16.254.01 是不合法的。

IPv6 地址由8组16进制的数字来表示,每组表示 16 比特。这些组数字通过 (“:”)分割。比如, 2001:0db8:85a3:0000:0000:8a2e:0370:7334 是一个有效的地址。而且,我们可以加入一些以 0 开头的数字,字母可以使用大写,也可以是小写。所以, 2001:db8:85a3:0:0:8A2E:0370:7334 也是一个有效的 IPv6 address地址 (即,忽略 0 开头,忽略大小写)。

然而,我们不能因为某个组的值为 0,而使用一个空的组,以至于出现 ( ::) 的情况。 比如, 2001:0db8:85a3::8A2E:0370:7334 是无效的 IPv6 地址。
同时,在 IPv6 地址中,多余的 0 也是不被允许的。比如, 02001:0db8:85a3:0000:0000:8a2e:0370:7334 是无效的。

说明: 你可以认为给定的字符串里没有空格或者其他特殊字符。
示例1
输入:“172.16.254.1”
返回值:“IPv4”

示例2
输入:“2001:0db8:85a3:0:0:8A2E:0370:7334”
返回值:“IPv6”

示例3
输入:“256.256.256.256”
返回值:“Neither”

思路:分别写一个判断IPv4的函数和IPv6函数,最后在总的判断函数中调用。
判断IPv4的条件:
将每一段放进数组,是一个字符串数组
(1)是否是4段(即判断数组长度是否为4)
(2)每一段中是否有空 NaN
(3)每一段中数字是否在0-255之间(字符串转化为Int判断)
(4)每一段中是否有0开头的(即判断字符串首位是否为0,单独的0是可以,即再加一个条件,判断字符串长度是否不等于1)

判断IPv6的条件:
将每一段放进数组,是一个字符串数组
(1)是否是8段(即判断数组长度是否为8)
(2)每一段中是否有空 NaN
(3)每一段的字符串成都是否大于4(大于4即不是IPv6)

/**
 * 验证IP地址
 * @param IP string字符串 一个IP地址字符串
 * @return string字符串
 */
function solve( IP ) {
    return checkIPv4(IP)?"IPv4":(checkIPv6(IP)?"IPv6":"Neither");
}
function checkIPv4(IP){
    let arr=IP.split(".");
    if(arr.length!==4) return false;
    for(let i of arr){
        if(Object.is(Number(i),NaN)||Number(i)>255||Number(i)<0||i[0]==='0'&&i.length!==1){
            return false;
        }
    }
    return true;
}
function checkIPv6(IP){
    let arr=IP.split(":");
    if(arr.length!==8) return false;
    for (let i of arr){
        if(i.length>4||Object.is(parseInt(i,16),NaN)){
            return false;
        }
    }
    return true;
}
module.exports = {
    solve : solve
};

总结:本题所用的知识点
1. String对象中的方法 split()
split() 方法用于把一个字符串分割成字符串数组

stringObject.split(separator,howmany)

参数说明
(1)separator:必需。字符串或正则表达式,从该参数指定的地方分割 stringObject。
(2)如果把空字符串 (“”) 用作 separator,那么 stringObject 中的每个字符之间都会被分割。
(3)howmany:可选。该参数可指定返回的数组的最大长度。如果设置了该参数,返回的子串不会多于这个参数指定的数组。如果没有设置该参数,整个字符串都会被分割,不考虑它的长度。

2. 数组长度以及字符串的长度

arr.length
s.length

3. for…of循环

for (variable of iterable) {
    //statements
}

参数说明:
variable:在每次迭代中,将不同属性的值分配给变量。
iterable:被迭代枚举其属性的对象。
举例:

//迭代Array
let iterable = [10, 20, 30];
for (const value of iterable) {
  console.log(value);
}
// 10
// 20
// 30

//迭代String
let iterable = "boo";
for (let value of iterable) {
  console.log(value);
}
// "b"
// "o"
// "o"

for…of语句在可迭代对象(包括 Array,Map,Set,String,TypedArray,arguments 对象等等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句

for…in和for…of的区别及用法
无论是for…in还是for…of语句都是迭代一些东西。它们之间的主要区别在于它们的迭代方式。
for…in 语句以任意顺序迭代对象的可枚举属性。
for…of 语句遍历可迭代对象定义要迭代的数据。
MDN 实例:

Object.prototype.objCustom = function() {};
Array.prototype.arrCustom = function() {};

let iterable = [3, 5, 7];
iterable.foo = 'hello';

console.log(iterable);

for (let i in iterable) {
    console.log(i); //  0, 1, 2, "foo", "arrCustom", "objCustom"
}

for (let i in iterable) {
    if (iterable.hasOwnProperty(i)) {
        console.log(i); // logs 0, 1, 2, "foo"
    }
}

for (let i of iterable) {
    console.log(i); // logs 3, 5, 7
}

在这里插入图片描述在这里插入图片描述
参考原文
以上三个结果中:
(1)console.log(iterable) 返回数组本身
(2)第一个for…in结果看出,可枚举属性除了本身的 0 , 1 , 2 ,foo之外,还有 arrCustom, objCustom。这是由于继承功能, iterable是数组实例,iterable.__proto__指向Array原型对象则有了前面定义的属性arrCustom, 而Array.__proto__指向Object原型对象,则有了前面定义的熟悉objCustom, 原型链在往上Object.__proto__指向null,此时终止继承。
(3)第二个for…in内部使用hasOwnProperty判断只有是本身的属性才输出

而for…of该循环迭代并记录iterable作为可迭代对象定义的迭代值,这些是数组元素 3, 5, 7,而不是任何对象的属性。

4. JavaScript内置对象Object中方法Object.is()
Object.is() 方法判断两个值是否为同一个值。

Object.is(value1, value2);

参数说明:
value1:被比较的第一个值。
value2:被比较的第二个值。
返回值:一个 Boolean 类型标示两个参数是否是同一个值。

描述:Object.is() 方法判断两个值是否为同一个值。如果满足以下条件则两个值相等:
都是 undefined;都是 null;都是 true 或 false;都是相同长度的字符串且相同字符按相同顺序排列;都是相同对象(意味着每个对象有同一个引用)
都是数字且都是 +0;都是 -0;都是 NaN;或都是非零而且非 NaN 且为同一个值

与== 运算不同。 == 运算符在判断相等前对两边的变量(如果它们不是同一类型) 进行强制转换 (这种行为的结果会将 “” == false 判断为 true), 而 Object.is不会强制转换两边的值。

与=== 运算也不相同。 === 运算符 (也包括 == 运算符) 将数字 -0 和 +0 视为相等 ,而将Number.NaN 与NaN视为不相等.

// 特例
Object.is(0, -0);            // false
Object.is(0, +0);            // true
Object.is(-0, -0);           // true
Object.is(NaN, 0/0);         // true

5. JavaScript全局对象中的parseInt() 函数
parseInt() 函数可解析一个字符串,并返回一个整数。

parseInt(string, radix)

参数说明:
string:必需。要被解析的字符串。
radix:可选。表示要解析的数字的基数。该值介于 2 ~ 36 之间。如果省略该参数或其值为 0,则数字将以 10 为基础来解析。如果它以 “0x” 或 “0X” 开头,将以 16 为基数。如果该参数小于 2 或者大于 36,则 parseInt() 将返回 NaN。

返回值:返回解析后的数字。
说明:当参数 radix 的值为 0,或没有设置该参数时,parseInt() 会根据 string 来判断数字的基数。举例,如果 string 以 “0x” 开头,parseInt() 会把 string 的其余部分解析为十六进制的整数。如果 string 以 0 开头,那么 ECMAScript v3 允许 parseInt() 的一个实现把其后的字符解析为八进制或十六进制的数字。如果 string 以 1 ~ 9 的数字开头,parseInt() 将把它解析为十进制的整数。

parseInt("10");			//返回 10
parseInt("19",10);		//返回 19 (10+9)
parseInt("11",2);		//返回 3 (2+1)
parseInt("17",8);		//返回 15 (8+7)
parseInt("1f",16);		//返回 31 (16+15)
parseInt("010");		//未定:返回 10 或 8
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值