ECMAScript中的正则表达式
理论
第一个问题:什么是正则表达式?
一个描述字符模式的对象,正则表达式中的字母和数字,都是按照字面含义进行匹配的。强大的字符串匹配工具。
第二个问题:如何建立一个正则表达式?
1、使用RegExp()构造函数创建RegExp对象。
2、特殊的直接量语法来创建,定义为包含在一对斜杠(/)之间的字符。 例如:var reg = /s$/ , var reg = new RegExp(s$) 两者效果完全相同,用来匹配所有以字母“s”结尾的字符串。
实战
实战部分我们从一个手机号码匹配的进化历程学习正则的实践原理
第一次实现-字符直接量:匹配自身
假设有一个手机号码为13762571094
/13762571094/.test(“13783281094”); // false
/13762571094/.test(“13762571094”); // true
/13762571094/.test(“ui13762571094dd”);// true
正则表达式在匹配时,只要输出匹配内容就返回true,不考虑前面的ui和后面的dd。最后这种情况显然不是我们想要的。
第二次实现-锚点:指定匹配位置
语法详细:
1、^匹配起始位置
/^http:/.test(“http://www.163.com”); // true
/^http:/.test(“ahttp://www.163.com"); //false
/^http:/.test(“https://www.163.com"); //false
2、$匹配结尾位置
/.jpg$/.test("1.jpg");//true
/.jpg$/.test("1.jpg png");//false
/.jpg$/.test("1.png");//false
/.jpg$/.test(“regexp.png");//false
3、\b匹配一个单词边界
正则表达式的“匹配”有两种概念,一种是匹配字符,一种是匹配位置。这里的“边界”就是匹配位置。
/\bis\b/.test(“this"); //false
/\bis\b/.test("that is reg”); //true
/\bis\b/.test(“thatisreg"); //false
/\B[Ss]cript/:与”JavaScript”和”/postscript”匹配,但不与”script”与”Script”。
实例改进:
所以在知道了锚点之后我们的正则有了第一次进化。
/^13762571094$/.test(“13762571094”); //true
/^13762571094$/.test(“ui13762571094dd");//false
/^13762571094$/.test(“13712345674");//false
在试过了多个号码后发现,这个正则只能识别这个标准的手机号码。这显然不是我们想要的,而不是识别一个手机号码的格式。
第三次实现-字符类:匹配一类字符中的一个
语法详细:
1、[abc]:a或b或c。[0-9]:一个数字(只要字符串中有一个数字就为true,定义是匹配字符串中是否有数字)
2、[^0-9]:非数字一个字符。[a-z]:一个字母(只要字符串有一个字母就为true,定义是匹配字符串中是否有字符)
3、.:任一字符(换行符除外)
/[0-9]/.test(“123”) //true
/[0-9]/.test(“asd") //false
/[^0-9]/.test(“asd") //true
/[a-z]/.test(“asd") //true
/./.test(“allen") //true
/./.test(“12") //true
实例改进:
/^1[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$/.test("13762571094");//true
/^1[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$/.test(“13712345678");//true
此刻是不是感觉和我一样,这显然太长了呢,继续往下看改进。
先来认识几个元字符,它们都是具有特殊意义的字符。
1、^、$、\b。
2、\d:[0-9]。\D:[^\d]
3、\s:空白符。\S:[^\s]
4、\w:[A-Za-z0-9_]。\W:[^\w]
/\d/.test(“123"); //true
/\d/.test(“1dsf"); //true
/\D/.test(“1dsf"); //true
/\D/.test(“123"); //false
实例进化:
/^1\d\d\d\d\d\d\d\d\d\d$/.test("13762571094");//true
/^1\d\d\d\d\d\d\d\d\d\d$/.test("13712345678");//true
/^1\d\d\d\d\d\d\d\d\d\d$/.test(“1376257109x");//false
是不是感觉代码比刚刚短了很多了呢?但这还是不够。
第四次实现-量词:出现的次数
1、{n,m}:n到m次。?:{0,1} 2、+:{1,}。*:{0,}
/\d*/.test(“abc");// true
/\d+/.test(“abc”);// false
/\d+/.test(“1abc");// true
/^https?:/.test(“http://www.163.com");// true
/^https?:/.test(“https://www.163.com");// true
/^https?:/.test(“httpss://www.163.com");// false
实例进化:
/^1\d{10}$/.test("13762571094");//true
/^1\d{10}$/.test("13712345678");//true
/^1\d{10}$/.test(“1376257109x”);//false
元字符
最后提一下转义符:也就是需要匹配的字符是元字符
那么这里有一个问题,什么是元字符呢?上面我们用过*,+,?,之类的符号,它们在正测表达式中都有一定的特殊含义,类似这些有特殊功能的字符都叫做元符。例如
var reg = /c*/;
表示有任意个c,但是如果我们真的想匹配c这个字符串的时候怎么办呢?只要将转义了就可以了,如下面这样子:
var reg = /c\*/;
var str='c*';
console.log(reg.exec(str)); // ["c*", index: 0, input: “c*"]
返回匹配的字符串:c*。
同理,要匹配其他元字符,只要在前面加上一个“\”就可以了。
回到正题。下面匹配需要转义的字符。
/http:\/\//.test("http://www.163.com");//true
/@163.com$/.test("abc@163.com");//true
/@163.com$/.test("abc@163acom");//true
/@163\.com$/.test("abc@163.com");//true
/@163\.com$/.test(“abc@163acom”);//false