理论

第一个问题:什么是正则表达式?

一个描述字符模式的对象,正则表达式中的字母和数字,都是按照字面含义进行匹配的。强大的字符串匹配工具。

第二个问题:如何建立一个正则表达式?

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