一、是什么

正则表达式是一种用来匹配字符串的强有力的武器

它的设计思想是用一种描述性的语言定义一个规则,凡是符合规则的字符串,我们就认为它“匹配”了,否则,该字符串就是不合法的

二、匹配规则

常见的校验规则如下:

规则 描述
\ 转义
^ 匹配输入的开始
$ 匹配输入的结束
* 匹配前一个表达式 0 次或多次
+ 匹配前面一个表达式 1 次或者多次。等价于 {1,}
? 匹配前面一个表达式 0 次或者 1 次。等价于{0,1}
. 默认匹配除换行符之外的任何单个字符
x(?=y) 匹配'x'仅仅当'x'后面跟着'y'。这种叫做先行断言
(?<=y)x 匹配'x'仅当'x'前面是'y'.这种叫做后行断言
x(?!y) 仅仅当'x'后面不跟着'y'时匹配'x',这被称为正向否定查找
(?<!y)x 仅仅当'x'前面不是'y'时匹配'x',这被称为反向否定查找
x|y 匹配‘x’或者‘y’
{n} n 是一个正整数,匹配了前面一个字符刚好出现了 n 次
{n,} n是一个正整数,匹配前一个字符至少出现了n次
{n,m} n 和 m 都是整数。匹配前面的字符至少n次,最多m次
[xyz] 一个字符集合。匹配方括号中的任意字符
[^xyz] 匹配任何没有包含在方括号中的字符
\b 匹配一个词的边界,例如在字母和空格之间
\B 匹配一个非单词边界
\d 匹配一个数字
\D 匹配一个非数字字符
\f 匹配一个换页符
\n 匹配一个换行符
\r 匹配一个回车符
\s 匹配一个空白字符,包括空格、制表符、换页符和换行符
\S 匹配一个非空白字符
\w 匹配一个单字字符(字母、数字或者下划线)
\W 匹配一个非单字字符

正则表达式标记

标志 描述
g 全局搜索。
i 不区分大小写搜索。
m 多行搜索。
s 允许 . 匹配换行符。
u 使用unicode码的模式进行匹配。
y

执行“粘性(sticky)”搜索,匹配从目标字符串的当前位置开始。

在了解下正则表达式基本的之外,还可以掌握几个正则表达式的特性:

贪婪模式

在了解贪婪模式前,首先举个例子:

const reg = /ab{1,3}c/

在匹配过程中,尝试可能的顺序是从多往少的方向去尝试。首先会尝试bbb,然后再看整个正则是否能匹配。不能匹配时,吐出一个b,即在bb的基础上,再继续尝试,以此重复

如果多个贪婪量词挨着,则深度优先搜索

const string = "12345";
const regx = /(\d{1,3})(\d{1,3})/;
console.log( string.match(reg) );
// => ["12345", "123", "45", index: 0, input: "12345"]

其中,前面的\d{1,3}匹配的是"123",后面的\d{1,3}匹配的是"45"

懒惰模式

惰性量词就是在贪婪量词后面加个问号。表示尽可能少的匹配

var string = "12345";
var regex = /(\d{1,3}?)(\d{1,3})/;
console.log( string.match(regex) );
// => ["1234", "1", "234", index: 0, input: "12345"]

其中\d{1,3}?只匹配到一个字符"1",而后面的\d{1,3}匹配了"234"

分组

分组主要是用过()进行实现,比如beyond{3},是匹配d字母3次。而(beyond){3}是匹配beyond三次

()内使用|达到或的效果,如(abc | xxx)可以匹配abc或者xxx

反向引用,巧用$分组捕获

let str = "John Smith";

// 交换名字和姓氏
console.log(str.replace(/(john) (smith)/i, '$2, $1')) // Smith, John

栈溢出(stack Overflow)

缓冲区溢出是由于C语言系列设有内置检查机制来确保复制到缓冲区的数据不得大于缓冲区的大小,因此当这个数据足够大的时候,将会溢出缓冲区的范围。

栈溢出就是缓冲区溢出的一种。 由于缓冲区溢出而使得有用的存储单元被改写, 往往会引发不可预料的后果。程序在运行过程中,为了临时存取数据的需要,一般都要分配一些内存空间,通常称这些空间为缓冲区。如果向缓冲区中写入超过其本身长度的数据,以致于缓冲区无法容纳,就会造成缓冲区以外的存储单元被改写,这种现象就称为缓冲区溢出。缓冲区长度一般与用户自己定义的缓冲变量的类型有关。

由于缓冲区溢出而使得有用的存储单元被改写,往往会引发不可预料的后果。向这些单元写入任意的数据,一般只会导致程序崩溃之类的事故,对这种情况我们也至多说这个程序有Bug。但如果向这些单元写入的是精心准备好的数据,就可能使得程序流程被劫持,致使不希望的代码被执行,落入攻击者的掌控之中,这就不仅仅是bug,而是漏洞(exploit)了。

栈溢出的解决方法:

减少栈空间的需求,不要定义占用内存较多的auto变量,应该将此类变量修改成指针,从堆空间分配内存。

函数参数中不要传递大型结构/联合/对象,应该使用引用或指针作为函数参数。

减少函数调用层次,慎用递归函数,例如A->B->C->A环式调用。

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,它是基于 JavaScript 的一个子集。数据格式简单, 易于读写, 占用带宽小

  • 同步:浏览器访问服务器请求,用户看得到页面刷新,重新发请求,等请求完,页面刷新,新内容出现,用户看到新内容,进行下一步操作
  • 异步:浏览器访问服务器请求,用户正常操作,浏览器后端进行请求。等请求完,页面不刷新,新内容也会出现,用户看到新内容

执行顺序不同

同步:在JavaScript中,同步操作意味着代码的执行顺序是从上到下,每一行代码都必须等上一行代码执行完毕后,才能进行下一行代码的执行。

异步:异步操作则允许我们在等待某些操作完成的同时进行其他操作。异步操作不会阻塞后面代码的执行,当异步操作完成时,通常会通过回调函数的方式通知我们。

阻塞与非阻塞不同

同步:由于同步代码必须按照顺序一行一行地执行,因此如果某个操作特别耗时,例如读取大文件、下载等,就会造成整个程序“阻塞”,影响了用户的体验。

异步:异步操作不会阻塞代码的执行。当异步操作完成,会在适当的时候插入主线程中继续执行。这样可以避免因等待耗时操作而阻塞主线程。

使用场景不同

同步:适用于一些依赖先后顺序的操作,例如:需要先登录后才能获取用户信息。

异步:适用于耗时的IO操作,例如网络请求、文件读写等。使得这些操作不会阻塞主线程的执行,提高了程序的性能。

代码结构不同

同步:代码结构简单直观,但是由于必须等待前一个操作完成后才能执行下一个操作,所以可能会导致程序的效率低下。

异步:代码结构相对复杂,但是可以大大提高程序的执行效率。在JavaScript中,异步编程常常通过回调函数、Promise、Async/Await等方式来实现。

拓展阅读

同步的概念

在计算机编程中,同步事件是指一次只能处理一个事件的情况。

异步的概念

异步是程序设计的一种方式,可以在等待某些操作的同时进行其他操作,不会阻塞后面代码的执行。

Ajax 的原理简单来说是在用户和服务器之间加了—个中间层( AJAX 引擎),由 XmlHttpRequest对象来向服务器发异步请求,从服务器获得数据,然后用 javascrip t 来操作 DOM 而更新页面。使用户操作与服务器响应异步化。这其中最关键的一步就是从服务器获得请求数据。

Ajax 的过程只涉及 JavaScript 、 XMLHttpRequest 和 DOM 。 XMLHttpRequest 是 ajax 的核心机制。

Ajax 的优点:

通过异步模式,提升了用户体验

优化了浏览器和服务器之间的传输,减少不必要的数据往返,减少了带宽占用

Ajax 在客户端运行,承担了一部分本来由服务器承担的工作,减少了大用户量下的服务器负载

Ajax 可以实现动态不刷新(局部刷新)

Ajax 的缺点:

安全问题 AJAX 暴露了与服务器交互的细节

对搜索引擎的支持比较弱

不容易调试

首先了解下浏览器的同源策略 同源策略 / SOP ( Same origin policy ) 是一种约定,由Netscape 公司 1995 年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到 XSS 、 CSFR 等攻击。所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个 ip 地址,也非同源。

通过 jsonp 跨域

document.domain + iframe 跨域

nginx 代理跨域

nodejs 中间件代理跨域

后端在头部信息里面设置安全域名解决跨域

这玩意一定要说全了装逼

用户输入阶段
合成 URL:浏览区会判断用户输入是合法 URL,比如用户输入的是搜索的关键词,默认的搜索引擎会合成新的,如果符合url规则会根据url协议,在这段内容加上协议合成合法的url

查找缓存
网络进程获取到 URL,先去本地缓存中查找是否有缓存资源,如果有则拦截请求,直接将缓存资源返回给浏览器进程;否则,进入网络请请求阶段;

DNS 解析:
DNS 查找数据缓存服务中是否缓存过当前域名信息,有则直接返回;否则,会进行 DNS 解析返回域名对应的 IP 和端口号,如果没有指定端口号,http 默认 80 端口,https 默认 443。如果是 https 请求,还需要建立 TLS 连接;

建立 TCP 连接:
TCP 三次握手与服务器建立连接,然后进行数据的传输;(三次握手开喷)

发送 HTTP 请求:
浏览器首先会向服务器发送请求行,它包含了请求方法、请求 URI 和 HTTP 协议的版本;另外还会发送请求头,告诉服务器一些浏览器的相关信息,比如浏览器内核,请求域名;

服务器处理请求:
服务器首先返回响应行,包括协议版本和状态码,比如状态码 200 表示继续处理该请求;如果是 301,则表示重定向,服务器也会向浏览器发送响应头,包含了一些信息;

页面渲染:

查看响应头的信息,做不同的处理,比如重定向,存储cookie 看看content-type的值,根据不同的资源类型来用不同的解析方式


浏览器渲染原理直接开干.....

浏览器将获取的HTML文档解析成DOM树。
处理CSS标记,构成层叠样式表模型CSSOM(CSS Object Model)。
将DOM和CSSOM合并为渲染树(rendering tree),代表一系列将被渲染的对象。
渲染树的每个元素包含的内容都是计算过的,它被称之为布局layout。浏览器使用一种流式处理的方法,只需要一次绘制操作就可以布局所有的元素。
将渲染树的各个节点绘制到屏幕上,这一步被称为绘制painting。

断开 TCP 连接:

数据传输完成,正常情况下 TCP 将四次挥手断开连接。但是如果浏览器或者服务器在HTTP头部加上 Connection: keep-alive,TCP 就会一直保持连接。

1.GET在浏览器回退不会再次请求,POST会再次提交请求

2.GET请求会被浏览器主动缓存,POST不会,要手动设置

3.GET请求参数会被完整保留在浏览器历史记录里,POST中的参数不会

4.GET请求在URL中传送的参数是有长度限制的,而POST没有限制

5.GET参数通过URL传递,POST放在Request body中

6.GET参数暴露在地址栏不安全,POST放在报文内部更安全

7.GET一般用于查询信息,POST一般用于提交某种信息进行某些修改操作

8.GET产生一个TCP数据包;POST产生两个TCP数据包

Ge和post的选择:

1.私密性的信息请求使用post(如注册、登陆)。

2.查询信息使用get。

1)共同点:三者都是浏览器的本地存储。

(2)区别:

   ①存储位置:cookie是由服务器端写入的,而SessionStorage、LocalStorage都是由前端写入的;

   ②存储大小:cookie的存储空间比较小,大概4KB,而SessionStorage、LocalStorage存储空间比较大,大概5M;

   ③生命周期:cookie的生命周期是由服务器端在写入的时候就设置好的,SessionStorage是页面关闭的时候就会自动清除,LocalStorage是写入就一直存在,除非手动清除;

   ④数据共享:三者的数据共享都遵循同源原则,SessionStorage还限制必须是同一个页面。

   ⑤发送请求时是否携带:在前端给后端发送请求的时候会自动携带cookie中的数据,但是SessionStorage、LocalStorage不会;

   ⑥应用场景:cookie一般用于存储登录验证信息SessionID或者token,SessionStorage可以用来检测用户是否是刷新进入页面,如音乐播放器恢复播放进度条功能,多页表单信息填写,LocalStorage常用于存储不易变动的数据,减轻服务器的压力。

1. cookies

介绍:cookie,意思是小甜饼,顾名思义,cookie 确实非常小,它的大小限制为 4KB 左右;每个             HTTP 请求都会带着 Cookie 的信息,所以 Cookie 当然是能精 简就精简!

常用的应用场景:判断用户是否登录。

针对登录过的用户,服 务器端会在他登录时往 Cookie 中加入一段加密过的唯一辨识单一用户的辨识码,下次只要读取这个值就可以判断当前用户是否登录啦。

2.localStorage

介绍:localStorage,它是 HTML5 标准中新加入的技术,localStorage 已经被大多数浏览器所支持;

sessionStorage,它与 localStorage 的接口类似,但保存数据的生命周期与 localStorage 不同,它只是可以将一部分数据在当前会话 中保存下来,刷新页面数据依旧存在。但当页面关闭后,sessionStorage 中的数据就 会被清空。

常用的应用场景:

localStorage 接替了 Cookie 管理购物车的工作,

HTML5 游戏通常会产生一些本地数据,localStorage 则是非常适合做 这个工作的。

3.sessionStorage  

介绍:sessionStorage,它与 localStorage 的接口类似,但保存数据的生命周期与 localStorage 不同。

它只是可以将一部分数据在当前会话 中保存下来,刷新页面数据依旧存在。但当页面关闭后,sessionStorage 中的数据就 会被清空。

常用的应用场景:

​ 如果遇到一些内容特别多的表单,为了优化用户体验,我们可能要把表 单页面拆分成多个子页面,然后按步骤引导用户填写。这时候 sessionStorage 的作用 就发挥出来了。

4.区别

特性 cookie sessjonStorage localstorage
数据生命期 生成时就会被指定一个maxAge值,这就是cookie的生存 周期,在这个周期内cookie有效,默认关闭浏览器失效 页面会话期间可用 除非数据被清除,否则一直 存在
存放数据大小 4K左右(因为每次http请求都会携带cookie) 一般5M或更大
与服务器通信 由对服务器的请求来传递,每次都会携带在HTTP头中 如果使用cookie保存过多数据会带来性能问题 数据不是由每个服务器请求传递的,而是只有在请求时使用数据,不参与和服务器的通信
易用性 cookie需要自己封装setCookie,getCookie 可以用源生接口,也可再次封装来对Object和 Array有更好的支持
共同点 都是保存在浏览器端,和服务器端的session机制不同

栈: 是一种连续储存的数据结构,具有先进后出后进先出的性质

通常的操作有入栈(压栈),出栈和栈顶元素。想要读取栈中的某个元素,就是将其之间的所有元素出栈才能完成。

堆: 是一种非连续的树形储存数据结构,具有队列优先,先进先出; 每个节点有一个值,整棵树是经过排序的。特点是根结点的值最小(或最大),且根结点的两个子树也是一个堆。常用来实现优先队列,存取随意。