回顾:正则表达式
[]:备选字符集,只能多选一。一个[]只能匹配一位字符
比如:我[去草]:我去 我草
[]内:
开头^:除了xx都行 [0123456789]-->[^47]
-:表示备选字符的范围: [a-z] [0-9] [A-Z]
预定义字符集:
[0-9] -->\d
[a-zA-Z_] -->\w
\s:空字符:\n \t 空格
量词:修饰前一位字符出现的次数
{min,max}:最少min个,最多max个
{min,}:最少min个,最多不限制
{num}:固定num个长度
验证座机号:
010-82838283
0311-12345678
0311-1234567 //注:如果遇到问题输入回车或者空格
匹配:\d{3,4}-\d{7,8}
正课:
特殊的数量词:+ * ?
?:可有可无,如果有,最多只能出现一次,
例:
我了?去 表示“了”可有可无,但是只能验证“我去”和“我了去”,不能
验证“我了了去”
*:可有可无,不限制个数
+:至少出现一次,不限制次数
():分组:为了改变模式的匹配顺序
例:身份证:匹配15位到18位的身份证\d{15}(\d{2}[0-9xX])?
匹配手机号:(\+86)?(\s)*1[3578]\d{9}
+86 13312345678
今后如果正文中出现+*?,都要用\转义
^:放在整个正则表达式的开头,表示以xxx开始
$:放在整个正则表达式的结尾,表示以xxx结束
?=:预判,判断在前一个字符之后,必须紧跟xxx
?!:预判,判断在前一个字符之后,必须不能跟xxx
课堂练习:
验证中文姓名:[\u4e00-\u9fa5]{2,6}
验证邮箱:zhangdong@tarena.com.cn 表达式\w+@\w+([-]\w+)*(\.\w+)+
其中\w+([-]\w+)*是一个以上的字母,后可跟“-字母”,可有可无,专门用
来匹配域名,“.字母”组合至少出现1次
RegExp对象:专门封装一条正则表达式,提供使用正则表达式的常用API
如何使用RegExp对象:1.创建;2.调用API
如何创建正则表达式对象:var regExp=/正则表达式/ig;
var regExp=/no/ig
RegExp对象的方法(API):
验证:var boolean=regExp.test("被检查的字符串")
如果验证通过:返回true;否则返回false
验证 vs 查找:
验证要求完整匹配,查找要求部分匹配
var regExp=/\w+@\w+([-]\w+)*(\.\w+)+/;
while(true){
var input=prompt("输入邮箱:");
if(regExp.test(input)){
document.write("注册成功");
break;
}else{
alert("邮箱格式有误");
}
}
//zhangdong@zhangdong@tarena.com.cn为什么test可以通过呢?那是因为
test方法默认只要找到,都会返回true,不管在什么位置。怎么样让test方法
完整匹配呢?在正则表达式前加^,后加$,今后验证都要加上
上例改进方法:
var regExp=/^\w+@\w+([-]\w+)*(\.\w+)+$/;
while(true){
var input=prompt("输入邮箱:");
if(regExp.test(input)){
document.write("注册成功");
break;
}else{
alert("邮箱格式有误");
}
}
查找:exec既能查找关键字的位置,又能找到关键字的内容
indexOf不支持正则,search支持正则,每次只能找1个
match得到所有内容,但是得不到位置
regExp.exec("被查找的内容")
arr[0]:里面保存的是关键字的内容,查找时会自动保存,每次查找后都会保
存在第0个位置,之前查找的如果不保存就会丢失
arr.index属性:找到的关键字的位置
exec方法每次只能找到1个,但是每次自动修改regExp对象的lastIndex属性。
regExp对象的lastIndex属性:表示下次开始匹配的位置
竖线“|”在正则表达式中表示“或”
exec找到头没了的时候,会返回null,这也是循环的条件
例:
var str="明明喜欢我,却不告诉我;别理我,我想静静;静静是谁?你TM先
告诉我明明是谁?";
var regExp=/明明|静静/g; //一般查找都要加g全局
var arr=[];
while((arr=regExp.exec(str))!=null){
//arr[0]关键字的内容;arr.index关键字的位置
document.write("在位置"+arr.index+"发现"+arr[0]+"<br/>");
}
关于查找:
如果仅判断有没有,或者仅查找位置:indexOf
如果仅判断有没有,或者仅查找位置,支持正则表达式:search()
如果仅找所有关键字的内容:match()
如果既找位置,又找内容:exec()
compile():编译,环境自己调用的
/正则表达式/:一般可应付绝大多数的环境或需求,但是根据用户需求在运行
时动态变化则用下面的var regExp=new RegExp("\\d{6}"); 动态创建正则表
达式,强调:字符串中所有的斜线都要用双斜线
例:
var regExp=/^\w+@\w+([-]\w+)*(\.\w+)+$/;
动态创建表达式如下:
var regExp=new RegExp("^\\w+@\\w+([-]\\w+)*(\\.\\w+)+$");
贪婪模式:.+ .*,这两种,默认是先匹配整个字符串,再缩小范围
懒惰模式:(.+?) (.*?),两种,从第一个字符开始,向后扩展范围
.是匹配任意字符
例:获取一段HTML文本中所有超链接的href属性的值
匹配超链接的正则表达式:<a(.+?)href\s*=\s*['"](.*?)['"](.*?)>
var txt='<script href="a.js"/>'+'<a href="cost/list.do">链接
1</a>'+'<a class="main" href="cost/add.do">链接2</a>';
var regExp=/<a(.+?)href\s*=\s*"(.*?)"(.*?)>/ig //查找,不用完
整匹配
var arr=[];
while((arr=regExp.exec(txt))!=null){
console.log(arr[0]);
}
查找功能中,正则表达式后面要加g,否则始终都是在第一个上面查找,形成
死循环。
从正则表达式匹配的内容中,取出一部分:RegExp.$n
$n:指正则表达式中的第几个分组,其实就是第几个圆括号
强调:正则表示的分组是从1开始,如上述例子中取第二个里面的元素:
console.log(RegExp.$2);
必须通过RegExp类型,直接调用$n,不能使用对象
用于模式匹配的String方法
所有模式匹配的API都支持正则表达式
String对象与正则表达式:
str=str.replace(/no/ig,"替换值")
var arr=str.match(/正则表达式/ig)
sr.search()
str.split(/正则表达式/)
例:
var str="那天,我去了她家。我说,我草";
str=str.replace(/我[去草]/g,"**");
document.write(str);
例:
var txt='<script href="a.js"/>'+'<a href="cost/list.do">链接
1</a>'+'<a class="main" href="cost/add.do">链接2</a>';
var regExp=/<a(.+?)href\s*=\s*"(.*?)"(.*?)>/ig //查找,不用完
整匹配
var arr=txt.match(regExp);
console.log(arr);
例:
var str="no zuo no die";
var words=str.split(" ");
for(var i=0;i<words.length;i++){
var first=words[i][0].toUpperCase();
words[i]=first+words[i].substring(1);
}
document.write(words.join(" "));
上述例子中如果单词间空格数超过1个,就会返回错误
var str="no zuo no die";
var words=str.split(/\s+/);
for(var i=0;i<words.length;i++){
var first=words[i][0].toUpperCase();
words[i]=first+words[i].substring(1);
}
document.write(words.join(" "));
trim功能:去除字符串开始和结尾的空格,中间空格不去掉。对输入字符串的
处理,多数要先清除开头和结尾空格,再处理
判断验证码是否正确(去除一个字符串开头和结尾的开头空格字符):
var code="4A7b";
while(true){
var input=prompt("输入验证码");
input=input.trim();
if(input.toLowerCase()==code.toLowerCase()){
document.write("登录成功");
break;
}else{
alert("验证码错误");
}
}
trim功能在IE8不支持!下面是在IE8中的代码:
function trim(str){
//使用正则表达式替换开头和结尾的空字符
var regExp=/(^\s+)|(\s+$)/g;
str=str.replace(regExp,"");
return str;
}
var code="4A7b";
while(true){
var input=prompt("输入验证码");
input=trim(input);
if(input.toLowerCase()==code.toLowerCase()){
document.write("登录成功");
break;
}else{
alert("验证码错误");
}
}
String总结:多有API都无法修改原字符串,都会返回新字符串。所有
StringAPI都需要用变量保存结果!
str.length 字符个数
str.toLowerCase()/toUpperCase()
查找关键字:
var index=str.indexOf("关键字"[,from]]) -->[]里面是可选的
var arr=str.match(/正则表达式/g)
获得字符串:
var substr=str.slice(start,end+1); -->数组里面方法
str.substring(start,end+1); --》正则表达式
str.substr(start,count);
替换:
str=str.replace(/正则表达式/g,"替换值");
获得指定位置的字符:
var char=str.charAt(index)
str[index]
字符编码解码:
var code=str.charCodeAt(index);
var char=String.fromCharCode(code);
RegExp对象总结:
var reg=/正则表达式/ig;
var reg=new RegExp("正则表达式",ig);其中所有的\都要改为\\
验证str中是否包含reg匹配的关键字:var boolean=reg.test(str);
强调:完整验证或完整替换,都需要在正则表达式前加^后加$while
((arr=reg.exec(str)
)!=null){
arr[0]} -->找到的一个关键字
arr.index -->当前关键字的位置
}
RegExp.$n:获得正则表达式中第n个分组(圆括号)匹配的子字符串
Math类型:封装了所有跟数学计算有关的API
不能new,即不能实例化得创建对象
Math.PI
Math.round(num)-->四舍五入取整
Math.ceil(num)-->向上取整
Math.floor(num)-->向下取整
var n=22.56;
Math.round(n) -->23
Math.ceil(n) -->23
Math.floor(n) -->22
Math.pow(底数,幂):n次方
Math.sqrt(num):平方根
Math.abs(num):取绝对值
var n=9;
Math.pow(n,3);
Math
Math.min/max(值1,值2,...)判断最大值和最小值
例:
var s1=75;
var s2=90;
var s3=80;
var arr=[2,4,1,7,6,3,9,8];
console.log(Math.max(s1,s2,s3)); //判断几个值得最大值
var max=Math.max.apply(Math,arr); //从数组arr中调用Math方法求最大值
console.log(max);
取数组中的最大值:var max=Math.max.apply(Math,arr)
随机数:Math.random():0<=r<1
任意min-max:Math.floor(Math.random()*(max-min+1)+min)
随机生成一个四位的随机验证码字符串:
step1:将所有字母,数字装入一个数组备用
var codes=[];
for(var i=48;i<=57;codes.push(i),i++); //数字
for(var i=65;i<=90;codes.push(i),i++); //大写字母
for(var i=97;i<=122;codes.push(i),i++); //小写字母
//数组中现在有62个元素,取下标0-61之间的随机数4个
var arr=[];
for(var i=0;i<4;i++){
var index=Math.floor(Math.random()*(61-0+1)+0);
var char=String.fromCharCode(codes[index]);
arr.push(char);
}
console.log(arr);
var code=arr.join("");
document.write("验证码:"+code);
使用方法来实现完整功能:
var codes=[];
for(var i=48;i<=57;codes.push(i),i++); //数字
for(var i=65;i<=90;codes.push(i),i++); //大写字母
for(var i=97;i<=122;codes.push(i),i++); //小写字母
//数组中现在有62个元素,取下标0-61之间的随机数4个
function getCode(){
var arr=[];
for(var i=0;i<4;i++){
var index=Math.floor(Math.random()*(61-0+1)+0);
var char=String.fromCharCode(codes[index]);
arr.push(char);
}
return arr.join("");
}
function trim(str){
var reg=/(\s+)|(\s+$)/g;
return str.replace(reg,"");
}
while(true){
var code=getCode();
var input=prompt("输入验证码:"+code);
input=trim(input);
if(input.toLowerCase()==code.toLowerCase()){
document.write("登录成功");
break;
}else{
alert("验证码错误!");
}
}
先用正则表达式来进行格式验证,再进行内容处理,修改方案:
var codes=[];
for(var i=48;i<=57;codes.push(i),i++); //数字
for(var i=65;i<=90;codes.push(i),i++); //大写字母
for(var i=97;i<=122;codes.push(i),i++); //小写字母
//数组中现在有62个元素,取下标0-61之间的随机数4个
function getCode(){
var arr=[];
for(var i=0;i<4;i++){
var index=Math.floor(Math.random()*(61-0+1)+0);
var char=String.fromCharCode(codes[index]);
arr.push(char);
}
return arr.join("");
}
function trim(str){
var reg=/(\s+)|(\s+$)/g;
return str.replace(reg,"");
}
while(true){
var code=getCode();
var input=prompt("输入验证码:"+code);
input=trim(input);
var reg=/[a-zA-Z0-9]{4}/;
if(reg.test(input)){
if(input.toLowerCase()==code.toLowerCase()){
document.write("登录成功");
break;
}else{
alert("验证码错误!");
}
}else{
alert("验证码格式错误");
}
}
Data对象:封装一个时间点数据,提供对时间、日期的常用API。
创建:var date=new Date();
1.创建Date类型的对象;2. 自动获得浏览器当前时间点
自定义时间:var date=new Date("2015-6-9 16:47")
1.创建Date类型的对象;2.自定义一个具体时间点
Date对象中,保存的是从1970年1月1日 0:00:00到现在的毫秒数!!!!
var date=new Date(0);相当于1970年1月1日 0:00:00 (国际标准时间,不
是北京时间)
var date=new Date(24*60*60*1000);1970年1月2日 0:00:00
例:
var d1=new Date(0);
console.log("原始时间:"+d1);
var now=new Date();
console.log("当前时间:"+now);
var birth=new Date("1991-1-2");
console.log("出生日期"+birth);
var ms=now-birth;
var days=ms/24/60/60/1000; //计算活了多少天
console.log("活了多少天:"+days);
var age=now.getFullYear()-birth.getFullYear();//计算年龄
console.log("年龄:"+age);
var minutes=30-now.getMinutes();
console.log("距离下课几分钟:"+minutes);
birth.setFullYear(2017); //set方法会直接修改原日期
var days=(birth-now)/24/60/60/1000;
console.log("距离生日还有"+days+"天");
var month=now.getMonth(); //返回值是当前月-1,因为月份是从0开始,到
11结束,因此需要在值后面加1才是当前月份
console.log("上月月份:"+month);
var month=now.getMonth()+1;
console.log("当前月份:"+month);
var day=now.getDay();
console.log("今天星期几"+day); //返回星期,星期日的值是0,星期一是1
,以此类推
var next=now+5*60*10000;
console.log("5分钟后时间"+next); //不能直接相加,返回的结果不对的.
结果并未加上,需要调用date.getTime()De得到时间毫秒数
var nowMs=now.getTime() //返回时间毫秒数
var nextMs=nowMs+5*60*1000; //毫秒数做加减,5分钟以后的时间
var next=new Date(nextMs); //将得到的毫秒数封装
console.log("5分钟后时间"+next);
API:
1.每个分量都有一对get/set方法,用来获取/设置该分量的值
2.命名:年/月/日:没有s
时/分/秒:有s
set方法会直接修改原日期
3.从取值或者赋值来说,除了每月中的日之外,其余都是从0开始,到-1结束
。
每月中的日,从1开始,到31结束
月份:取值时,+1修正;赋值时,-1修正。
星期:从星期日到开始到星期六结束,值从0~6
日期计算:两日期对象相减,得到毫秒数
时间做+:var nowMs=now.getTime() //返回时间毫秒数
var nextMs=nowMs+5*60*1000; //毫秒数做加减,5分钟以后的时间
var next=new Date(nextMs); //将得到的毫秒数封装
console.log("5分钟后时间"+next);
使用毫秒做计算,不改变原时间对象,需要重新封装时间对象。
上述对象加减封装的方法,是有限制的,最大仅能算到“天数”,再算“月数
”,无法确定每月天数。