目录
1.7 把 JSON 文本转换为 JavaScript 对象
1.JSON
JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
- SON 指的是 JavaScript Object Notation, JS 对象简谱
- JSON 是轻量级的数据交换格式
- JSON 独立于语言
- JSON 是“自描述的”且易于理解
JSON 的语法是来自 JavaScript 对象符号的语法,但 JSON 格式是纯文本。读取和生成 JSON 数据的代码可以在任何编程语言编写的。
1.1JSON 实例
JSON 语法定义了一个雇员对象:包含三条员工记录的数组(对象):
JSON 实例
{ "employees":[ {"firstName":"Bill", "lastName":"Gates"}, {"firstName":"Steve", "lastName":"Jobs"}, {"firstName":"Alan", "lastName":"Turing"} ] }
JSON 与 JS 对象的关系
很多人搞不清楚 JSON 和 JS 对象的关系,甚至连谁是谁都不清楚。其实,可以这么理解:
JSON 是 JS 对象的字符串表示法,它使用文本表示一个 JS 对象的信息,本质是一个字符串。
1 |
|
2 |
|
JSON 和 JS 对象互转
要实现从JSON字符串转换为JS对象,使用 JSON.parse() 方法:
1 |
|
要实现从JS对象转换为JSON字符串,使用 JSON.stringify() 方法:
2 |
|
1.2 JSON 格式评估为 JavaScript 对象
JSON 格式在语法上与创建 JavaScript 对象的代码相同。
由于这种相似性,JavaScript 程序可以很容易地将 JSON 数据转换成本地的 JavaScript 对象。
1.3 JSON 语法规则
-
数据是名称/值对
-
数据由逗号分隔
-
花括号保存对象
-
方括号保存数组
1.4 JSON 数据 - 名称和值
JSON 数据的书写方式是名称/值对,类似 JavaScript 对象属性。
名称/值对由(双引号中的)字段名构成,其后是冒号,再其后是值:
"firstName":"Bill"
JSON 名称需要双引号。JavaScript 名称不需要。
1.5 JSON 对象
JSON 对象是在花括号内书写的。
类似 JavaScript,对象能够包含多个名称/值对:
{"firstName":"Bill", "lastName":"Gates"}
1.6 JSON 数组
JSON 数组在方括号中书写。
类似 JavaScript,数组能够包含对象:
"employees":[ {"firstName":"Bill", "lastName":"Gates"}, {"firstName":"Steve", "lastName":"Jobs"}, {"firstName":"Alan", "lastName":"Turing"} ]
在上面的例子中,对象 "employees" 是一个数组。它包含了三个对象。
每个对象代表一个人的一条记录(带有名和姓)。
1.7 把 JSON 文本转换为 JavaScript 对象
JSON 的通常用法是从 web 服务器读取数据,然后在网页中显示数据。
为了简单起见,可以使用字符串作为输入演示。
首先,创建包含 JSON 语法的 JavaScript 字符串:
var text = '{ "employees" : [' + '{ "firstName":"Bill" , "lastName":"Gates" },' + '{ "firstName":"Steve" , "lastName":"Jobs" },' + '{ "firstName":"Alan" , "lastName":"Turing" } ]}';
然后,使用 JavaScript 的内建函数 JSON.parse() 来把这个字符串转换为 JavaScript 对象:
var obj = JSON.parse(text);
最后,请在您的页面中使用这个新的 JavaScript 对象:
实例:
<p id="demo"></p>
<script>
document.getElementById("demo").innerHTML =
obj.employees[1].firstName + " " + obj.employees[1].lastName;
</script>
2.正则表达式
regular expression:RegExp (处理字符串的一种规则)
-
用来「处理字符串」的一种规则(只能处理字符串,不是字符串不能处理,但是可以使用
toString()
方法变为字符串,哈哈哈哈,有没有被绕蒙,下面举个栗子理解一下吧) -
他是一个「规则」:可以验证字符串是否符合某个规则(test),也可以把字符串中符合规则的内容捕获到(exec/match...)
2.1 编写正则表达式
2.1.1 创建方式
1)字面量创建方式
两个斜杆之间包起来的,都是用来描述规则的元字符
let reg1 = /\d+/;
2)构造函数模式创建
使用正则对象 new
的方式,写成字符串形式的
//说明,字符串中直接`\d`是输出的d,因此需要使用`\`转义一下,
let reg2 = new RegExp('\\d+');
不管使用以上哪种方式创建,得到的都是对象数据类型的。虽然 reg1 和 reg2 的规则一样,但是
reg1!==reg2
,其实就是他们的堆内存地址不一样。
2.1.2 正则表达式的组成
1)元字符
-
量词元字符:设置出现的次数
元字符 | 含义 |
---|---|
* | 零到多次 |
+ | 一到多次 |
? | 零到一次 |
{n} | n 次 |
{n,} | n 到多次 |
{n,m} | n 到 m 次 |
-
特殊元字符:单个或者组合在一起代表特殊的含义
元字符 | 含义 |
---|---|
\ | 转义字符 |
. | 除\n(换行符)之外的任意字符 |
^ | 以哪一个元字符开头 |
$ | 以哪一个元字符结尾 |
\n | 换行符 |
\d | 0-9 之间的一个数字(包含 0 和 9) |
\D | 除 0-9 之间的一个数字 |
\w | 数字、字母、下划线中的任意一个字符 |
\s | 一个空白字符(包含空格、制表符、换页符) |
\t | 一个制表符(一个 TAB 键,四个空格) |
\b | 匹配一个单词的边界 |
x|y | x 或 y 中的一个字符 |
[xyz] | x 或 y 或 z 中的一个字符 |
[^xy] | 除了 x 和 y 以外的任意一个字符 |
[a-z] | 指定 a-z 这个范围的任意字符 |
[^a-z] | 上一个的取反“非” |
() | 正则中的分组符号 |
(?:) | 只匹配不捕获 |
(?=) | 正向预查 |
(?!) | 反向预查 |
普通元字符:代表本身含义的
-
/name/
此正则就是去匹配字符串中的'name'
2)修饰符:放在正则表达式外面/j/g
修饰符 | 含义 |
---|---|
i(ignoreCase) | 忽略大小写匹配 |
m(multiline) | 可以进行多行匹配 |
g(global) | 全局匹配 |
u(Unicode) | 用来正确处理大于\uFFF 的 Unicode 字符 |
y(sticky) | 粘连 |
s(dotAll) | 让'.'能匹配任意字符,包含\n\r |
2.1.3 常用元字符的详解
1)^ $
在我们写正则表达式的时候,为了更加严谨,一般都要加上这两个元字符,然后把我们的规则写在他们之间(如果不写^$ 的话,我们写的规则有时会出现意想不到的事情,哈哈,别着急,一步步来。下面介绍到{n,m}的时候会结合它一起说明)
-
^ 以什么元字符开始
-
$ 以什么元字符结尾
-
^/$ 两个都不加匹配的是:字符串中包含符合规则的内容即可
-
^/$ 两个都加匹配的是:字符串只能是和规则一致的内容
//匹配的是:以数字开头的字符串
let reg = /^\d/;
console.log(reg.test('name')); //false
console.log(reg.test('2020name')); //true
console.log(reg.test('name2020')); //false
复制代码
//匹配的是:以数字结尾的字符串
let reg = /\d$/;
console.log(reg.test('name')); //false
console.log(reg.test('2020name')); //false
console.log(reg.test('name2020')); //true
复制代码
// ^/$ 两个都不加匹配的是:字符串中包含符合规则的内容即可
let reg1 = /\d/;
console.log(reg1.test('as2')); //true
//^/$ 两个都加匹配的是:字符串只能是和规则一致的内容
let reg2 = /^\d$/
console.log(reg2.test('as2')); //false
console.log(reg2.test('22')); //false
console.log(reg2.test('2')); //true
2)\
-
转义字符,他可以把没有意义的转为有意义的,也可以把有意义的变为没有意义的
//‘.’ 是代表除换行符之外的任意字符,而不是小数点
let reg = /^2.3$/;
console.log(reg.test('2.3')); //true
console.log(reg.test('2@3')); //true
console.log(reg.test('23')); //false
//现在我们把‘.’变为一个普通的小数点(使用到的就是\)
let reg = /^2\.3$/;
console.log(reg.test('2.3')); //true
console.log(reg.test('2@3')); //false
3)x|y
-
x 或 y:直接 x|y 会存在优先级问题,一般配合小括号进行分组使用,因为小括号改变处理的优先级 => 小括号:分组
-
//匹配的是:以18开头或者以29结尾的都可以,以1开头以9结尾,8或2都可以,所以不加括号怎么理解都可以 //以下的匹配结果都为true let reg = /^18|29$/; console.log(reg.test('18')); console.log(reg.test('29')); console.log(reg.test('129')); console.log(reg.test('189')); console.log(reg.test('1829')); console.log(reg.test('182')); //以上不加括号我们可以有很多理解方式都是对的,但是我们加上括号,就不可能想上面那样理解了; //匹配的是:18或者29中的一个,其余都是false let reg = /^(18|29)$/; console.log(reg.test('18')); console.log(reg.test('29')); console.log(reg.test('129')); console.log(reg.test('189'));
4) []
-
中括号中出现的字符「一般」都代表它本身的含义(会消磁,把他本身的意义都消除掉了)
-
\d 在中括号里面的含义仍然是 0-9,这个没有消磁
-
[18]:代表的是 1 或者 8 中的任意一个
-
[10-29]:代表的是 1 或者 9 或者 0-2
//下面的‘.’就是小数点的意思
let reg = /^[.]+$/;
复制代码
//匹配的含义是:只能是@或者+的
let reg = /^[@+]$/;
console.log(reg.test('@')); //true
console.log(reg.test('+')); //true
console.log(reg.test('@@')); //false
console.log(reg.test('@+')); //false
复制代码
//匹配的含义是:\d还是代表0-9
let reg = /^[\d]$/;
console.log(reg.test('9')); //true
console.log(reg.test('\\')); //false
console.log(reg.test('d')); //false
复制代码
//匹配的含义是:1或者8
let reg = /^[18]$/;
console.log(reg.test('1')); //true
console.log(reg.test('8')); //true
console.log(reg.test('18')); //false
复制代码
//匹配的含义是:1或者0-2或者9
let reg = /^[10-29]$/;
//匹配的含义是:1或者0-2或者9或'('或')'
let reg = /^[(10-29)]$/;
5) {n,m}
它是代表前面的元字符出现 n 到 m 次,
下面的例子中,不加^$ 的超出范围的虽然返回的是 true,但是在使用 exec 捕获的时候,最多捕获 4 个。
//这个正则匹配的是数字出现2到4次即可,明显第三个超出了,应该返回false,但是结果却是true,但是加上^$ 就不一样了
let reg = /\d{2,4}/;
reg.test('1'); //false
reg.test('14'); //true
reg.test('123456'); //true
//加上^$ 之后的结果:这个就代表只能有2-4位数字,超过就多余,而上一个匹配的是只有字符串中出现2-4次即可,因此加上^$ 更加严谨
let reg = /^\d{2,4}$/;
reg.test('1'); //false
reg.test('14'); //true
reg.test('123456'); //false
6)分组作用
-
1.就是改变默认的优先级;
-
2.分组捕获;
-
3.分组引用
//第一个作用:提升优先级
let reg1 = /^18|29$/;
let reg2 = /^(18|29)$/
复制代码
//第二个作用:使用exec捕获的时候不仅可以得到整个大正则的结果,也会分别拿到每一个分组内的
let reg1 =/^([1-9]\d{5})((19|20)\d{2})(0[1-9]|10|11|12)(0[1-9]|[1-2]\d|30|31)\d{3}(\d|x)$/i;
复制代码
//第三个作用:第一位是a-z的字母,分组1,;第二位也是a-z的字母,分组2;第三位\2是和第二个分组出现一模一样的内容...
let reg1 =/^([a-z])([a-z]\2\1)$/
7)分组的具名化(给分组起名字)?<名字>
let str = '132123201203200000';
let reg = /^(?<A>[1-9]\d{5})(?<B>(19|20)\d{2})(?<C>0[1-9]|10|11|12)(?<D>0[1-9]|[1-2]\d|30|31)\d{3}(\d|x)$/i;
let res = reg.exec(str);
console.log(res);
console.log(res.groups.B);//可以直接拿到B组的内容
8)问号在正则中的五大作用
-
1.问号左边是非量词元字符:本身代表量词元字符,出现零到一次;
-
2.问号左边是量词元字符:取消捕获时候的贪婪性;
-
-
(?:):只匹配不捕获;
-
-
4.(?=):正向预查;
-
-
(?!)负向预查
-
2.2 常用的正则表达式
2.2.1 验证手机号
-
11 位
-
第一位是数字 1
-
第二位是数字 3-9 中的任意一位
let reg = /^1[3-9]\d{9}$/;
console.log(reg.test('13245678945')); //true
console.log(reg.test('1324567895')); //false
console.log(reg.test('12245678945')); //false
2.2.2 验证是否为有效数字
规则:
-
开头可以有+ -
-
整数位:
-
如果是一位数可以是 0-9 任意数;
-
如果是多位数,首位不可以是 0;
-
-
小数位:如果有小数位,那么小数位后面至少有一位数字,也可以没有小数位
let reg = /^[+-]?(\d|[1-9]\d+)(\.\d+)?$/;
console.log(reg.test('0.2')); //true
console.log(reg.test('02.1')); //false
console.log(reg.test('20.')); //false
2.2.3 验证密码
规则:
-
6-16 为组成
-
必须由数字字母组成
let reg = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[\d(a-z)(A-Z)]{6,16}$/;
2.2.4 验证真实姓名
规则:
-
必须是汉字
-
名字长度 2-10 位
-
可能有译名:·汉字
补充:怎么打出中间位置的点:中文状态下,ESC 下面的那个键就可以
let reg = /^[\u4E00-\u9FA5]{2,10}(·[\u4E00-\u9FA5]{2,10})?$/;
2.2.5 验证邮箱
规则:
-
邮箱的名字以‘数字字母下划线-.’几部分组成,但是-/.不能连续出现也不能作为开头 \w+((-\w+)|(.\w+))*;
-
@ 后面可以加数字字母,可以出现多位 @[A-Za-z0-9]+ ;
-
对@后面名字的补充:多域名 .com.cn ;企业域名 (.|-)[A-Za-z0-9]+)*
-
.com/.cn 等域名 .[A-Za-z0-9]+
let reg = /^\w+((-\w+)|(\.\w+))*@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/
2.2.6 验证身份证号
规则:
-
18 位
-
最后一位是数字或者 X
-
前 6 位是省市县
-
后四位是年
-
后两位是月 01-12
-
后两位是日 01-31
-
最后四位
-
最后一位:X 或者数字
-
倒数第二位:偶数:女 奇数:男 小括号分组的作用:分组捕获,不仅可以把大正则匹配信息捕获到,还可以单独捕获到每个小分组的内容
let reg =/^([1-9]\d{5})((19|20)\d{2})(0[1-9]|10|11|12)(0[1-9]|[1-2]\d|30|31)\d{3}(\d|x)$/i;