正则表达式
正则表达式(Regular Expression)是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。
一、字符及含义
- 元字符
字符 | 含义 |
---|---|
\t | 水平制表符 |
\r | 回车符 |
\n | 换行符 |
\f | 换页符 |
\v | 垂直制表符 |
\0 | 空字符 |
- 预定义类
字符 | 等价类 | 含义 |
---|---|---|
. | [^\r\n] | 除了回车符和换行符之外的所有字符 |
\d | [0-9] | 数字字符 |
\D | [^0-9] | 非数字字符 |
\s | [\t\n\x0B\f\r] | 空白字符 |
\S | [^\t\n\x0B\f\r] | 非空白字符 |
\w | [a-zA-Z_0-9] | 单词字符,字母、数字下划线 |
\W | [^a-zA-Z_0-9] | 非单词字符 |
- 边界
字符 | 含义 |
---|---|
^ | 以xxx开头 |
$ | 以xxx结尾 |
\b | 单词边界 |
\B | 非单词边界 |
- 量词
字符 | 含义 |
---|---|
? | 出现零次或一次(最多出现一次) |
+ | 出现一次或多次(最少出现一次) |
* | 出现零次或多次(出现任意次) |
{n} | 出现n次 |
{n,m} | 出现n到m次 |
{n,} | 至少出现n次 |
- 式尾修饰符
字符 | 含义 |
---|---|
g | global,全文搜索,不加的话搜索到第一个结果即停止 |
i | ignore case,忽略大小写,默认大小写敏感 |
m | multiple lines,多行搜索 |
二、贪婪模式与非贪婪模式
- 贪婪模式:量词在默认下是尽可能多的匹配。
'123456789'.match(/\d{3,5}/g); //["12345", "6789"]
- 非贪婪模式:让正则表达式尽可能少的匹配,一旦成功匹配不再继续尝试。做法很简单,在量词后加上
?
即可。
'123456789'.match(/\d{3,5}?/g); //["123", "456", "789"]
三、表达式练习
- 判断用户输入的是不是合法的用户名(长度6-20个字符,只能包括字母、数字、下划线):
function isValidUsername(str){
var val = /^\w{6,20}$/;
var result = false
if(val.exec(str)) result = true;
return result;
}
- 判断用户输入的是不是手机号:
function isPhoneNum(str){
var val = /^1[3578]\d{9}$/;
var result = false
if(val.exec(str)) result = true;
return result;
}
- 判断用户输入的是不是邮箱:
function isEmail(str){
var val = /^[\w-]+@[\w-]+(\.[\w-]+)*\.[a-zA-Z0-9]{2,6}$/;
var result = false
if(val.exec(str)) result = true;
return result;
}
- 去除字符串两边的空白字符:
function trim(str){
return str.replace(/^\s+|\s+$/g,"");
}
定时器
JavaScript提供定时执行代码的功能,叫做定时器(timer),主要由setTimeout()和setInterval()这两个函数来完成。
一、setTimeout()
setTimeout函数用来指定某个函数或某段代码,在多少毫秒之后执行。它返回一个整数,表示定时器的编号,以后可以用来取消这个定时器。
var timerId = setTimeout(func|code, delay)
上面代码中,setTimeout函数接受两个参数,第一个参数func|code
是将要推迟执行的函数名或者一段代码,第二个参数delay
是推迟执行的毫秒数。
二、setInterval()
setInterval函数的用法与setTimeout完全一致,区别仅仅在于setInterval指定某个任务每隔一段时间就执行一次,也就是无限次的定时执行。
三、clearTimeout(),clearInterval()
setTimeout和setInterval函数,都返回一个表示计数器编号的整数值,将该整数传入clearTimeout和clearInterval函数,就可以取消对应的定时器。
四、单线程模型
单线程模型指的是JavaScript 只在一个线程上运行。也就是说,JavaScript 同时只能执行一个任务,其他任务都必须在后面排队等待。
注意,JavaScript 只在一个线程上运行,不代表 JavaScript 引擎只有一个线程。事实上,JavaScript 引擎有多个线程,单个脚本只能在一个线程上运行(称为主线程),其他线程都是在后台配合。
五、任务队列
- JavaScript 运行时,除了一个正在运行的主线程,引擎还提供一个任务队列(task queue),里面是各种需要当前程序处理的异步任务。(实际上,根据异步任务的类型,存在多个任务队列。为了方便理解,这里假设只存在一个队列。)
- 首先,主线程会去执行所有的同步任务。等到同步任务全部执行完,就会去看任务队列里面的异步任务。如果满足条件,那么异步任务就重新进入主线程开始执行,这时它就变成同步任务了。等到执行完,下一个异步任务再进入主线程开始执行。一旦任务队列清空,程序就结束执行。
- 异步任务的写法通常是回调函数。一旦异步任务重新进入主线程,就会执行对应的回调函数。如果一个异步任务没有回调函数,就不会进入任务队列,也就是说,不会重新进入主线程,因为没有用回调函数指定下一步的操作。
- JavaScript 引擎怎么知道异步任务有没有结果,能不能进入主线程呢?答案就是引擎在不停地检查,一遍又一遍,只要同步任务执行完了,引擎就会去检查那些挂起来的异步任务,是不是可以进入主线程了。这种循环检查的机制,就叫做事件循环(Event Loop)。
六、运行机制
- setTimeout和setInterval的运行机制是,将指定的代码移出本次执行,等到下一轮Event Loop时,再检查是否到了指定时间。如果到了,就执行对应的代码;如果不到,就等到再下一轮Event Loop时重新判断。这意味着,setTimeout指定的代码,必须等到本次执行的所有代码都执行完,才会执行。
- setTimeout(f,0)将第二个参数设为0,作用是让f在现有的任务(脚本的同步任务和“任务队列”中已有的事件)一结束就立刻执行。也就是说,setTimeout(f,0)的作用是,尽可能早地执行指定的任务,而不是立刻执行。