1、RegExp 简介

  RegExp 即正则表达式(Regular Expression,在代码中常简写为 regex、regexp或RE/re/reg),就是使用单个字符串来描述、匹配一系列符合某个句法规则的字符串搜索模式,搜索模式可用于文本搜索和文本替换。

  正则表达式是由一个字符序列形成的搜索模式,当你在文本中搜索数据时,你可以用搜索模式来描述你要查询的内容,也就是说正则表达式是描述字符模式的对象,可用于对字符串模式匹配及检索替换,是对字符串执行模式匹配的强大工具。

  所谓正则表达式,直接可理解为规则或者模式表达式,就是表达了某一种计算机可以理解的规则,而一般人很难读懂的文字表达方式,可用于所有文本搜索和文本替换的操作,简单说就是处理字符串。

2、字符串方法

  (1)、charAt()  获取某个字符,返回字符串某一位的字符。

  (2)、split()  分割字符串,获得数组。

  (3)、search()  查找某个字符首次出现的位置,配合正则使用更好,返回值为数值,没找到返回-1。

  (4)、match()  查找字符串中指定字符并返回该字符,如果不使用正则,则只返回首次出现的指定字符,不会再向后匹配,如果使用正则并进行全局匹配,则以数组形式返回字符串中所有指定的字符,没找到则返回null。

  (5)、replace()  替换字符,返回一个新字符串,配合正则使用更好,可以替换所有匹配。

 <script>
var str = 'abcdefgca'; //返回字符串中某一位的字符。
alert(str.charAt(3)); //返回:d //查找字符串首次出现的位置。
alert(str.search('z')); //返回:-1 //查找指定的字符。
//只返回第一次出现的c,不再向后匹配。
alert(str.match('c')); //返回:c //将'a'替换为'i'。
//只替换了第一个位置的a,不再向后匹配。
alert(str.replace('a', 'i')); //返回:ibcdefgca //分割字符串。
var str1 = '12-56-aaa-89-cd';
var arr = str1.split('-'); //返回:12,56,aaa,89,cd
alert(arr);
</script>

 

  实例:使用普通方法找出字符串中所有数字

  实现思路:要找出字符串中的数字,其实也不难,使用判断先将字符串中的数字提取出来,那么字符串中肯定不止一个数字,所以就需要一个空字符串来存储提取出来的数字字符,然后再将这些数字字符添加到数组中,最后返回,这样就完成了。来看看程序是怎么实现的:

 <script>
var str = '12 abc 3d4 aa56 78c9 21zz -=-=889s-';
var arr = [];
var num = '';
//首先循环遍历字符串
for(var i=0; i<str.length; i++){
//再判断当前字符大于等于0并且小于等于9,则为数字
if(str.charAt(i)>='0' && str.charAt(i)<='9'){
//那么就将当前的字符存储在空字符串中
num += str.charAt(i);
}
else{
//如果字符串中有值。
if(num){
//将值添加到数组中。
arr.push(num);
//再清空字符串,避免重复添加。
num='';
}
}
}
//最后在整个字符串结束之后有可能还会有数字,再做一次判断。
if(num){
//如果还有值就添加到数组中。
arr.push(num);
//再清空字符串。
num = '';
}
//返回:OK,现在返回就完成了。
alert(arr); //返回:12,3,4,56,78,9,21,889
</script>

  虽然可以使用普通方法完成,结构清晰,但是代码相对较长,如果使用正则,那么一个表达式就完成了这么多工作,非常方便,下面就来看看怎么使用正则。

3、使用正则

  正则表达式语法:var re = new RegExp('模式', '修饰符');

  模式就是表达式的模式,而修饰符是用于指定全局匹配、不区分大小写等,完整形态就是正则表达式。

  看到正则语法长这模样,不就是 JS 中典型的新创建对象的语法么,对了,就是新创建一个正则对象。我们都知道,要尽量避免使用 new 关键词,使用 new 无疑就是新创建了一个对象,那么同时就预示着其占据了一定的内存空间,如果处理不当,积累多了会造成内存溢出,这样相当耗费资源,不利于代码优化的实现。同时这样的写法,体现不出正则的强大,他应该是很简洁的才对,因此在实际使用的时候都不采用这种 JS 风格的正则语法,都使用的是另一种风格,如下:

  语法:var re = /模式/修饰符;

  这种风格就相对简洁了,属于一般人看不懂的表达方式。

  (1)、修饰符

  修饰符用于执行全局匹配和区分大小写。

  忽略大小写:i (ignore的简写,中文翻译为:忽视)

  全局匹配:g (global的简写,中文翻译为:全部的/全局的)

  实例:全局搜索指定字符

 <script>
var str = 'AbCdEFgiX'; //JS风格:
//这个正则表达式什么也不代表,只代表abc本身。
var reg = new RegExp('abc', 'i');
alert(str.match(reg)); //返回:AbC //常用风格:
var re = /efg/i;
alert(str.match(re)); //返回:EFg
</script>

4、方括号和元字符

  (1)、方括号

  方括号用于查找某个范围内的字符。

  ①、任意字符

  表达式:[abc]

  查找方括号中的任意字符。

  [] 在这里为或的意思,即随便出现哪个都行。

 <script>
var str = 'apc xpc ppc bpc spc opc';
//[apx]pc,随便出现哪个都行,即:apc ppc xpc
var re = /[apx]pc/g; alert(str.match(re)); //返回前3个pc。
</script>

  ②、范围查找

  表达式:[0-9] [a-z] [A-z] [A-Z]

  [0-9]  查找任意 0 - 9 的数字。

  [a-z]  查找任意 a - z 的字符。

  [A-z]  查找任意 大写A - 小写z 的字符。

  [A-Z]  查找任意 大写A - 大写Z的字符。

  ③、排除查找

  表达式:[^abc] [^a-z] [^0-9]

  [^abc]  查找任意不在方括号中的字符。

  [^a-z]  查找任意除了字母以外的字符,包括数字符号中文外文。

  [^0-9]  查找任意除了数字以外的字符,包括字母符号中文外文。

 <script>
var str = 'o1t out o.t o t o`t ot2 3ot';
//o和t中间除了数字,什么都可以
var re = /o[^0-9]t/g; alert(str.match(re)); //返回:out,o.t,o t,o`t
</script>

  ④、选择查找

  表达式:(a|b|c)

  查找任何指定的选项,a 或 b 或 c。

  ⑤、匹配还可以使用组合模式,比如:[a-z0-9A-Z] [^a-z0-9]

  [a-z0-9A-Z]  任意大小写字母和数字。

  [^a-z0-9]  除了字母和数字以外,什么都可以。

  (2)、元字符

  元字符是拥有特殊含义的字符,也可以叫做转义字符。

  下面是一些常用的元字符:

元字符 描述 使用
. 查找单个字符,代表任意字符,不包括换行和行结束符。 不建议使用,容易出问题。
\w 查找单词字符,包括英文数字下划线,相当于[a-z0-9] /\w/
\W 查找非单词字符,相当于[^a-z0-9] /\W/
\d 查找数字,相当于[0-9] /\d/
\D 查找非数字,相当于[^0-9] /\D/
\s 查找空白字符,包括空格符、回车符、制表符、换行符和换页符,不可显示不可打印的字符。 /\s/
\S 查找非空白字符。 /\S/
\b 查找位于单词的开头或结尾的匹配,如果未匹配到,则返回null。 /\b/
\B

查找非单词边界的匹配,也就是不位于开头或结尾,匹配位置的上一个和下一个字符的类型是相同的:即必须同为单词,

或必须同为非单词,字符串的开头和结尾处被视为非单词字符,如果未匹配到,则返回null。

/\B/
\n 查找换行符,如果找到则返回该位置,如果未找到则返回-1。 /\n/ 
\f 查找换页符。 /\f/ 
\r 查找回车符。 /\r/ 
\t 查找制表符。 /\t/ 

5、量词

  所谓量词,就是数量词,即个数,用在正则中,表示出现的次数。

  下面是一些常用的量词:

量词 描述 使用
* 零次或任意次,相当于{0,} 不推荐使用,范围太广,不够精确。
? 零次或一次,相当于{0, 1} /10?/g 对1进行全局搜索,包括其后紧跟的零个或1个'0'。
+ 一次或任意次,相当于{1, } /w+/g 对至少一个单词进行全局搜索。
{n} 正好n次 /d{4}/g 对包含四位数的数字进行全局搜索。
{n,} 至少n次,最多不限 /d{3,}/g 对包含至少三位数的数字进行全局搜索。
{n, m} 至少n次,最多m次  /d{3,4}/g 对包含三位或四位的数字进行全局搜索。

  下面是一些常用的匹配模式:

模式 描述 使用
^a 任何开头为 a 的字符,表示行首 /^\d/ 以数字开头 /^a/g 全局搜索以'a'开头的字符
a$ 任何结尾为 a 的字符,表示行尾 /\d$/ 以数字结尾 /z$/g 全局搜索以'z'结尾的字符
?=a 任何其后紧跟 a 的字符 /a(?= b)/g 全局搜索'a'后紧跟'b'的字符
?!a 任何其后没有紧跟 a 的字符 /c(?= d)/g 全局搜索'c'后没有紧跟'd'的字符

6、字符串和正则配合

  (1)、search() 配合正则

  实例:找出字符串中第一次出现数字的位置

 <script>
var str = 'asdf 34 21 zxcvbnm'; //元字符\d,表示转义为数字
var re = /\d/; alert(str.search(re)); //返回:5 第一个数字为3出现在第5位
</script>

  (2)、match() 配合正则

  其实没有什么东西是非正则不可的,只是正则可以让做东西更方便。下面就完成本章遗留的历史问题,怎么使用正则,能一句代码就完成普通方法需要很多行代码才能完成的东西。

  在实例之前,先看看 match() 与正则的配合:

 <script>
var str = 'as8d99999f 34 21 zxcv567m'; //找出字符串中的数字可以使用元字符\d
var re = /\d/;
//没告诉系统要找多少数字,系统在找到数字后就返回
alert(str.match(re)); //返回:8 //因此需要全局匹配,使用修饰符g
var re = /\d/g;
//没告诉系统要找几位,系统会将所有找到的数字返回
alert(str.match(re)); //返回:8,9,9,9,9,9,3,4,2,1,5,6,7 //所以可以使用两个元字符,告诉系统要找的数字是2位
var re = /\d\d/g;
//显然这样是不可取的,因为数字的位数并不固定,可能是1位,有可能还是多位
alert(str.match(re)); //返回:99,99,34,21,56 //所以需要用到量词+,+代表若干,也就是多少都可以。
var re = /\d+/g;
//现在返回正确。
alert(str.match(re)); //返回:8,99999,34,21,567
</script>

  实例:使用正则找出字符串中所有数字

 <script>
var str = '12 abc 3d4 aa56 78c9 21zz -=-=889s-'; //alert(str.match(/\d+/g));
//元字符\d也可以使用[0-9]代替,0到9随便哪个都行。
alert(str.match(/[0-9]+/g)); //返回:12,3,4,56,78,9,21,889
</script>

  正则是强大的字符串匹配工具,就这样简单的使用一句代码就完成了。

  (3)、replace() 配合正则

 <script>
var str = 'abc zaaz deaxcaa';
//将字符串中的a替换为数字0
alert(str.replace('a', 0)); //仅仅只将第一个a替换为0 //配合正则使用匹配所有a再替换
var re = /a/g;
alert(str.replace(re, '0')); //返回所有的a都为0
</script>

  实例:简单的敏感词过滤

  所谓的敏感词,就是法律不允许的词语,一切非法词都可以叫做敏感词,这包括的范围就太广了,比如危害国家安全,反对宪法确立的基本原则,散步谣言,扰乱民心,扰乱社会秩序,破坏社会稳定,色情、暴力、赌博、虚假、侵害、骚扰、粗俗、猥亵或其他道德上令人反感的词,以及含有法律规定或禁止的其他内容的词语等。在平时最常见也是大多数人都会用的词莫属道德上令人反感的词了,说斯文一点就是吵架时用于攻击别人的词语。这里就列举几个热门的网络词语作为例子。

 <!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JavaScript实例</title>
<script>
window.onload = function (){
var oBtn = document.getElementById('btn1');
var oTxt1 = document.getElementById('txt1');
var oTxt2 = document.getElementById('txt2'); oBtn.onclick = function (){
//这里的|在正则中表示 或 的意思
var re = /元芳|萌萌哒|然并卵|毛线|二货|城会玩/g;
//文本框2的值等于文本框1的值过滤掉敏感词
oTxt2.value = oTxt1.value.replace(re,'***');
};
};
</script>
</head>
<body>
<textarea id="txt1" rows="10" cols="40"></textarea><br>
<input id="btn1" type="button" value="过滤"><br>
<textarea id="txt2" rows="10" cols="40"></textarea>
</body>
</html>

  可在第一个文本框中输入一些相关语句,点击过滤按钮,查看过滤后的效果。

  此外,支持正则表达式的 String 对象的方法还包括 split() 方法,可把字符串分割为字符串数组。

7、RegExp 对象方法

  在 JS 中,RegExp 对象是一个预定义了属性和方法的正则表达式对象。

  (1)、test()

  test() 方法用于检测一个字符串是否匹配某个模式,也就是检测指定字符串是否含有某个子串,如果字符串中含有匹配的文本,返回 true,否则返回 false。

  语法:RegExpObject.test(str)

  调用 RegExp 对象 re 的 test() 方法,并为它传递字符串 str,与这个表示式是等价的:(re.exec(str) != null)。

  实例:搜索字符串是否含有指定的字符

 <script>
var str = 'The best things in life are free, like hugs, smiles, friends, kisses, family, love and good memories.'; var re = /i/;
alert(re.test(str)); //返回:true var reg = /z/;
alert(reg.test(str)); //返回:false //上面的代码可以不用定义正则的变量,直接使用,将两行合并为一行。
alert(/i/.test(str));
alert(/z/.test(str));
</script>

  

  (2)、exec()

  exec() 方法用于检索字符串中的正则表达式的匹配,提取指定字符串中符合要求的子串,该方法返回一个数组,其中存放匹配的结果。如果未找到匹配,则返回 null。可以使用循环提取所有或者指定 index 的数据。

  语法:RegExpObject.exec(str)

  exec() 方法的功能非常强大,它是一个通用的方法,可以说是 test() 方法的升级版,因为他不仅可以检测,而且检测到了可以直接提取结果。该方法使用起来比 test() 方法以及支持正则表达式的 String 对象的方法更为复杂。

 <script>
var str = 'good good study day day up';
var re = /good/; var arr = re.exec(str);
console.log(arr);  //控制台显示:["good"]点开后显示:0 "good",index 0,input "good good study day day up"。
console.log(arr.index);  //控制台显示:0
console.log(arr.input);  //控制台显示:good good study day day up
</script>

  通过上面的实例,可以看到,如果 exec() 找到了匹配的文本,则返回一个结果数组。否则,返回 null。此数组的第 0 个元素是与正则表达式相匹配的文本,第 1 个元素是与 RegExpObject 的第 1 个子表达式相匹配的文本(如果有的话),第 2 个元素是与 RegExpObject 的第 2 个子表达式相匹配的文本(如果有的话),以此类推。

  除了数组元素和 length 属性之外,exec() 方法还返回两个属性。index 属性声明的是匹配文本的第一个字符的位置。input 属性则存放的是被检索的字符串 string。我们可以看出,在调用非全局的 RegExp 对象的 exec() 方法时,返回的数组与调用方法 String.match() 返回的数组是相同的。 

  什么是"与子表达式相匹配的文本"?

  所谓的子表达式就是正则表达式中包含在圆括号中的内容。看下面实例:

 <script>
var str = 'good good study day day up';
var re = /g(o+)d/;
var arr = re.exec(str);
console.log(arr); //显示:["good", "oo"]点开后显示:0 "good", 1 "oo", index 0,input: "good good study day day up"
console.log(arr.length); //显示:2 var reg = /(o+)/;
//var reg = /o+/; 只返回一个"oo",长度为1
var arr1 = reg.exec(str);
console.log(arr1); //显示:["oo", "oo"]点开后显示:0 "oo", 1 "oo", index 1,input: "good good study day day up"
console.log(arr1.length); //显示:2
</script>

  通过上例,可以看到,子表达式是一个大的表达式的一部分,并且必须用()包含起来。一个表达式可使用多个子表达式,同时还支持多层嵌套,把一个表达式划分为多个子表达式的目的是为了把那些子表达式当作一个独立的元素来使用。也就是说表达式中的子表达式可以作为整个表达式返回,也可以作为一个单独的表达式返回。所以上面的数组长度为 2。

  使用子表达式是为了提取匹配的子字符串,表达式中有几个 () 就有几个相应的匹配字符串,顺序会依照 () 出现的顺序依次进行,并且 () 中可以使用 或"|" 进行多个选择。也就是说可以使用 () 对字符进行分组,并保存匹配的文本。

  如果该方法使用全局匹配,则找到第一个指定字符,并存储其位置,如果再次运行 exec(),则从存储的位置(lastIndex)开始检索,并找到下一个指定字符,存储其位置。lastIndex 属性是 RegExp 对象属性,是一个整数,标示开始下一次匹配的字符位置。看下面实例:

 <script>
var str = 'good good study day day up';
var re = /good/g;
var arr;
do{
arr = re.exec(str);
console.log(arr);
console.log(re.lastIndex);
}
while(arr !== null)
/*
结果如下:
显示:["good"],点开后:0 "good", index 0, input "good good study day day up"。
lastIndex为4。 显示:["good"],点开后:0 "good", index 5, input "good good study day day up"。
lastIndex为9。 显示:null
lastIndex为0。
*/
</script>

  在调用非全局的 RegExp 对象的 exec() 方法时,返回的数组与调用 String.match() 返回的数组是相同的。但是,当 RegExpObject 是一个全局正则表达式时,exec() 的行为就稍微复杂一些。它会在 RegExpObject 的 lastIndex 属性指定的字符处开始检索字符串 string。当 exec() 找到了与表达式相匹配的文本时,在匹配后,它将把 RegExpObject 的 lastIndex 属性设置为匹配文本的最后一个字符的下一个位置。这就是说,可以通过反复调用 exec() 方法来遍历字符串中的所有匹配文本。当 exec() 再也找不到匹配的文本时,它将返回 null,并把 lastIndex 属性重置为 0。

  通过上面实例,可以看到,当第三次循环时,找不到指定的 "good",于是返回 null,lastIndex 值也变成 0 了。找到的第一个 "good" 的 lastIndex 值为 4,是匹配文本最后一个字符的下一个位置。

 <script>
var str = 'good good study day day up';
var re = /good/g;
var arr;
while((arr = re.exec(str)) != null){
console.log(arr);
console.log(re.lastIndex);
}
/*
结果如下:
显示:["good"],点开后:0 "good", index 0, input "good good study day day up"。
lastIndex为4。 显示:["good"],点开后:0 "good", index 5, input "good good study day day up"。
lastIndex为9。
*/
</script>

  这里需要注意,如果在一个字符串中完成了一次模式匹配之后要开始检索新的字符串(仍然使用旧的 re),就必须手动地把 lastIndex 属性重置为 0。

  无论 RegExpObject 是否是全局模式,exec() 都会把完整的细节添加到它返回的数组中。这就是 exec() 与 String.match() 的不同之处,后者在全局模式下返回的信息要少得多。因此可以这么认为,在循环中反复地调用 exec() 方法是唯一一种获得全局模式的完整模式匹配信息的方法。

  (3)、compile

  compile() 方法用于在脚本执行过程中编译正则表达式,也可用于改变和重新编译正则表达式。主要作用是改变当前(re)匹配模式。

  语法:RegExpObject.compile(模式, 修饰符)

  模式就是正则表达式,修饰符用于规定匹配的类型,g 匹配全局,i 忽略大小写,gi 全局匹配忽略大小写。

  该方法是改变匹配模式时使用的,一般情况下,能用到的地方很少。

  实例:在全局中忽略大小写 搜索"day",并用 "天" 替换,然后通过 compile() 方法,改变正则表达式,用 "日" 替换 "Today" 或 "day"。

 <script>
var str = 'Today is a beautiful day, Day day happy!';
var re = /day/gi;
var str1 = str.replace(re, '天');
console.log(str1); //输出:To天 is a beautiful 天, 天 天 happy! reg = /(to)?day/gi;
reg.compile(reg);
str1 = str.replace(reg, '日');
console.log(str1); //输出:日 is a beautiful 日, 日 日 happy!
</script>

8、正则应用

  正则表达式也叫规则表达式,所以在编写时,和编写 JS 的流程一样,先虑再写。最重要的就是,先要搞清楚他所要表达的规则,仔细端详其外表,看他到底长什么模样,也就是以什么样的格式存在,再根据这种格式去写表达式,看是否能达到我们预期的目的,如果未达到,其实一般情况下直接将格式描述成表达式,都不会达到预期的效果,好在我们的主框架已经有了,我们只需要知道是什么地方出错了,什么地方没有达到预期,就可以很简单的在这个框架基础上稍加修改,最后就是完美的表达式了。比如要写一个验证手机号的正则表达式,手机号大家都知道是 11 位,全部为数字,而且开头是 1,紧跟着的 2 位,因为运营商不同,可有多种组合,后面 8 位是任意数字,所以我们就可以规定开头必须为 1,后面 2 位根据各运营商提供的不同组合进行限定,最后再输入 8 位任意数字。这样主框架就算完成了,但是手机号也有特殊情况,比如移动给手机号码前边加上 +86 依然可以使用,必要的时候我们还需要把这种情况考虑进去,不然用户输入了自己的移动手机号给前边加了个 +86,然后点击提及,系统 "啪" 弹出一个窗口,你输入的是毛线,系统不识别,这样就闹笑话了,所以再只需要对框架做出修改,把这种情况考虑进去,就大功告成了。

  这么说起来正则表达式貌似很简单的样子,其实挺难的,why are you so diao?归根结底就是这种一般人很难看懂的表达方式,自己当时写的时候很明白表达的是什么,过段时间回头,哎哟我去,怎么不认识了。其实这是一个熟能生巧的过程,记得有篇课文中写到“好记性不如烂笔头”,勤能补拙,多动手多写多思考,通过码海战术,反复推敲代码,让自己身经百战,见的多了,自然就不虚了,编程是一门艺术,精通任何一门艺术,都需要大量的练习和领悟,知识就是一个积累的过程,当然更重要的还是要自己去总结归纳,让知识真正属于自己。我觉着写程序这东西吧,最重要的还是思维,让代码始终跟着这种思维走,目的只有一个,怎么简单怎么省事怎么做,当然不是偷工减料,要明白需要什么,不需要什么,要呈现出什么样的效果,应该怎么去一步步实现,只要有这种实现目的的思维,就可以让代码始终保持着清晰简洁的状态,加快编写代码的效率,还有助于排错,也有利于代码的优化。那个好像扯太远了,每个人都有自己思考问题的方式,有不同的做事风格,只要最优化解决问题就好了,回到正事,接下来看看正则表达式应用的两个实例。

  (1)、正则验证 QQ 号

  思路分析:QQ 号有一个特性全部为数字,而且第一位不为 0,那么就可以这样写 /^[1-9]/,开头为 1-9 随便哪个数字,常见的 QQ 号最少的是 5 位数,最多的是 10 位数,那么可以使用量词 {n,m} 限定位数,表达式为 /\d{5,10}/,这有一个小问题,前边我们已经限定了开头的第一位,那就说明还可以再输入至少 4 位,最多 9 位的数字,这样才匹配了最少 5 位最多 10 位,将表达式改为 /\d{4,9}/,最后再限定结尾不能是非数字,就完事了。下面看代码是怎么完成的:

 <!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JavaScript实例</title>
<script>
window.onload = function (){
var oBtn = document.getElementById('btn1');
oBtn.onclick = function (){
var oTxt = document.getElementById('txt1').value;
var re = /^[1-9]\d{4,9}$/;
//用定义的正则表达式检测输入框的值是否匹配。
if(re.test(oTxt)){
alert("格式正确");
}
else{
alert('输入错误');
}
};
};
</script>
</head>
<body>
<input id="txt1" type="text" placeholder="请输入QQ">
<input id="btn1" type="button" value="验证">
</body>
</html>

  (2)、正则验证邮箱

  思路分析:先端详下邮箱的外表,随便来个 abc123_@ss789.xyz,邮箱是典型的粗俗的分析下其结构组成,大致可分为五部分,第一部分若干字母、若干数字还有一个下划线,第二部分是一个 @,第三部分又是若干字母、若干数字,第四部分是一个点,最后一部分又是若干字母,诶、邮箱长的好复杂,各种若干。现在我们看光了邮箱的模样,清楚了邮箱的规则,就可以使用表达式描述了,第一部分可写为 /\w+/,表示若干英文,第二部分就采用 @,第三部分可表达为 [a-z0-9]+,若干字母数字都可以,第四部分需要注意,点在正则中代表任意字符,如果想直接显示为点,就需要使用转义,就写为 \.,最后一部分若干英文,表达为 [a-z]+,这样就用正则的规则把邮箱的规则描述完了,最后再使用忽略大小写,将格式整理下:/\w+@[a-z0-9]+\.[a-z]+/  下面就用我们分析的表达式直接验证一下:

 <!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JavaScript实例</title>
<script>
window.onload=function (){
var oBtn=document.getElementById('btn1');
var oTxt=document.getElementById('txt1');
oBtn.onclick=function (){
var re=/\w+@[a-z0-9]+\.[a-z]+/i;
if(re.test(oTxt.value)){
alert('合法邮箱');
}
else{
alert('非法邮箱');
}
};
};
</script>
</head>
<body>
<input id="txt1" type="text" placeholder="请输入邮箱">
<input id="btn1" type="button" value="验证">
</body>
</html>

  将我们上面用于分析的邮箱例子 abc123_@ss789.xyz 拿来检测,OK,合法邮箱,这就没问题了吗?我们再来验证下这个邮箱:正则abc123_@ss789.xyz 校验,OK,还是合法邮箱,这邮箱看着都不正规,跟我们之前分析的邮箱样子,长的从本质上都不一样,正则怎么会判断合法呢?这不是我们要的效果,显然是我们的表达式有点小问题,就像之前说的,一般情况下直接将格式描述成表达式,都不会达到预期的效果,那怎么解决呢?先来分析下是什么原因导致的,其实是因为正则对象方法 test() 造成的,该方法有一个特性:只要这个字符串其中的一部分符合要求,就返回 true。解决方法其实也很简单,让整个字符串都被正则检测,而不只是检测一部分,所以再加上行首行尾就 OK 了。其实熟练了正则之后,像这样的小问题,一般也不可能出现,这里注重点是思路,要养成一种编写代码的思维模式。

 <!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JavaScript实例</title>
<script>
window.onload=function (){
var oBtn=document.getElementById('btn1');
var oTxt=document.getElementById('txt1');
oBtn.onclick=function (){
var re=/^\w+@[a-z0-9]+\.[a-z]+$/i;
if(re.test(oTxt.value)){
alert('合法邮箱');
}
else{
alert('非法邮箱');
}
};
};
</script>
</head>
<body>
<input id="txt1" type="text" placeholder="请输入邮箱">
<input id="btn1" type="button" value="验证">
</body>
</html>

  现在对刚才的 2 个邮箱再次验证,第一个合法,第二个非法,这个正则验证邮箱的表达式就没问题了。其实还是不够严谨,现在网站大多要填邮箱的地方,邮箱的服务器地址也就是后缀名如 @qq.com 等都提供了下拉列表,可供用户选择,如果是需要整个邮箱都自行输入,那么这个正则表达式问题就来了,邮箱的后缀名可以分为几类,其第三部分和最后一部分都是固定的格式,如果使用该表达式验证,那事就大了,因为我们给每一部分定义的都是可输入若干任意字符,很显然这是非法的格式,邮箱的后缀是需要做限定的,这里只是简单的做一个实现思路的分析,在真正用的时候,还需要具体问题具体对待。像这种需要验证的东西,前端不可能做到完美,前端就算写的再严谨,也是很容易出问题的,所以这是属于后端干的事,但是前端可以对用户的输入做一个简单的格式验证,只有确保用户输入正确了,再配合后端,那就是事半功倍的。

JavaScript学习总结【7】、JS RegExp的更多相关文章

  1. Javascript学习记录——原生JS实现旋转木马特效

    昨天学习到了JS特效部分,然后老师讲了旋转木马特效的实现,如上图.不过只是讲了通过点击箭头实现图片的切换,对于点击图片本身以及二者联动却是没有讲解. 本着一颗追求完美的心,今天花费了一个中午终于将整个 ...

  2. javascript学习一、js的初步了解

    1.javascript的简介: *javascript 是一种基于对象和事件驱动的语言,主要应用于客户端. -- 基于对象:  ** 提供了很多对象,可以直接使用. --事件驱动: ** html做 ...

  3. JavaScript学习02(js快速入门)

    快速入门 基本语法 JavaScript的语法和Java的语法类似,每个语句以;结束,语句块用{...}.但是JavaScrip并不强制要求在每个语句的结尾加;,浏览器中负责执行JavaScript代 ...

  4. JavaScript学习01(js概述)

    JavaScript概述 JavaScript历史 要了解JavaScript,我们首先要了解一下JavaScript的诞生. 在上个世纪的1995年,当时的网景公司正凭借其Navigator浏览器成 ...

  5. 【JavaScript学习整理】js基础

    HTML,CSS属于标记语言, JavaScript是基于客户端的脚本语言. 变量: 语法  var 变量名 = value var是系统内部关键字,用来声明变量 变量名规则:  1.不能以数字开头  ...

  6. javascript学习5、JS面向对象

    创建对象的几种常用方式 1.使用Object或对象字面量创建对象 2.工厂模式创建对象 3.构造函数模式创建对象 4.原型模式创建对象 1.使用Object或对象字面量创建对象 JS中最基本创建对象的 ...

  7. javascript学习笔记(四) Number 数字类型

    数字格式化方法toFixed().toExponential().toPrecision(),三个方法都四舍五入 toFixed() 方法指定小数位个数  toExponential() 方法 用科学 ...

  8. JavaScript学习12 JS中定义对象的几种方式

    JavaScript学习12 JS中定义对象的几种方式 JavaScript中没有类的概念,只有对象. 在JavaScript中定义对象可以采用以下几种方式: 1.基于已有对象扩充其属性和方法 2.工 ...

  9. JavaScript学习10 JS数据类型、强制类型转换和对象属性

    JavaScript学习10 JS数据类型.强制类型转换和对象属性 JavaScript数据类型 JavaScript中有五种原始数据类型:Undefined.Null.Boolean.Number以 ...

  10. JavaScript学习06 JS事件对象

    JavaScript学习06 JS事件对象 事件对象:当事件发生时,浏览器自动建立该对象,并包含该事件的类型.鼠标坐标等. 事件对象的属性:格式:event.属性. 一些说明: event代表事件的状 ...

随机推荐

  1. openstack 调试

  2. Java Stream 使用详解

    Stream是 Java 8新增加的类,用来补充集合类. Stream代表数据流,流中的数据元素的数量可能是有限的,也可能是无限的. Stream和其它集合类的区别在于:其它集合类主要关注与有限数量的 ...

  3. Java的垃圾回收概述

    Java语言建立了垃圾收集机制,即GC,用以跟踪正在使用的对象和发现并回收不再使用的对象,垃圾清理势在必行,以下讲述java垃圾收集算法. 1.Java垃圾收集算法的核心思想 Java语言建立了垃圾收 ...

  4. How to easily concatenate text based on criteria in Excel? 如何将Excel中的文本按条件合并

    To combine text with the unique ID numbers, you can extract the unique values first and then create ...

  5. 日志分析(php+nosql+rsync+crontable)

    是不是经常要分析用户的行为?是不是经常遇到多台server上传的日志一起分析?是不是对数据统计的间隔时间要求非常短?还有木有由于日志文件过大,而须要分块处理? 1.说明一点在日志写入的时候必须依照一种 ...

  6. [rxjs] Demystifying Cold and Hot Observables in RxJS

    Cold: console.clear(); var Observable = Rx.Observable; var clock = Observable.interval(1000).take(10 ...

  7. pcap 安装(debian7 linux) qt 使用pcap.h

    安装方法一.sudo apt-get install libpcap-dev 安装方法二. 去http://www.tcpdump.org/下载最新的libpcap.tar.gz包 解压以后 ./co ...

  8. 【转】Enable ARC in a Cocos2D Project: The Step-by-Step-How-To-Guide Woof-Woof!

    On April 5, 2012, in idevblogaday, by Steffen Itterheim http://www.learn-cocos2d.com/2012/04/enablin ...

  9. PureMVC(JS版)源码解析(十二):Facade类

    MVC设计模式的核心元素在PureMVC中体现为Model类.View类和Controller类.为了简化程序开发,PureMVC应用Facade模式.    Facade是Model\View\Co ...

  10. 将Java应用注册为后台服务

    项目中有一个java应用程序,交付后用户要求要把这个程序做成后台服务程序,即:系统启动后该程序可以自动启动,并且在前台不要出现运行窗口,维护人员只要在“服务管理”(Windows)中选择启动或停止即可 ...