正则表达式简介

正则表达式是很多高级语言都拥有的功能,用来对字符串进行验证、检索、替换操作等。正则表达式让字符

串处理如虎添翼。

JavaScript 中,正则表达式用两个正斜杠当做字面量,比如/abc/就是一个正则表达式。用 typeof 检测

正则表达式的类型将得到“object”,因为正则表达式是一个引用类型值

正则表达式单独使用没有意义,它的功能只体现在对字符串的操作上。比如/abc/可以作为字符串的 test()

方法的参数,来检查一个字符串中是否出现“abc”子串,例如:

/abc/.test("mmmabcmmm"); //true,因为字符串中出现了 abc

/abc/.test("mmmabmmmc"); //false,因为字符串中没有出现 abc

/abc/.test("mmmabc"); //true,因为字符串中出现了 abc

什么是 “ 模式 ”

正则表达式的 test()方法非常有用,可以用来检测字符串是否匹配某种“模式”,语法是:

正则表达式.test(待检测字符串); //结果布尔值 true 或者 false

什么是模式呢?看一个题目:验证字符串是否符合规定的电话号码格式“000-12345678”,即以 3 位数字

开头,短横后是 8 位数字。

正确书写题目要求的正则表达式是解决题目的关键。我们要写一个“以 3 位数字开头,短横后是 8 位数字”

的“模式”。这个模式如何书写呢?思路是:按位书写,从开头到结尾,一位一位按顺序规定字符串这一位能够

出现的字符是什么。

正则表达式中用\d 表示数字字符,^表示这是字符串的开头,$表示这是字符串的结尾。题目要求的正则表

达式可以这样写:

/^\d\d\d\-\d\d\d\d\d\d\d\d\d$/

正则表达式书写一种模式的时候是按位书写的,我们要一位一位按顺序规定字符串这一位能够出现的字符是

什么。\d 表示这一位只能出现数字,而短横“-”之前也加了反斜杠“\”,这是因为正则表达式中符号普遍有

一些特殊的意义,加上反斜杠可以进行“转义”从而让符号表示此符号本身,而不使用特殊的功能。^和$分别表

示这是字符串的结尾。

这个正则表达式可以正确工作,例如:

/^\d\d\d\-\d\d\d\d\d\d\d\d$/.test("010-12345678"); //true,符合模式

/^\d\d\d\-\d\d\d\d\d\d\d\d$/.test("010-1234567") //false,不符合模式

/^\d\d\d\-\d\d\d\d\d\d\d\d$/.test("01012345678") //false,不符合模式

这就是正则表达式的思维:按位书写,从开头到结尾,一位一位按顺序规定字符串这一位能够出现的字符是

什么。

使用正则表达式提供的“量词”可以简化模式的书写。我们可以将“以 3 位数字开头,短横后是 8 位数字”

的正则表达式简化为:

/^\d{3}\-\d{8}$/

大括号中的数字就是量词,表示它前面的这个字符模式出现的次数。这个正则表达式可以正确工作,例如:

/^\d{3}\-\d{8}$/.test("010-12345678"); //true,符合模式

/^\d{3}\-\d{8}$/.test("010-1234567") //false,不符合模式

/^\d{3}\-\d{8}$/.test("01012345678") //false,不符合模式

字符串相关方法

字符串有 4 个方法可以使用正则表达式当做参数,见表 7-1。

表 7-1 字符串可以使用正则表达式的方法

方法 功能

split() 根据匹配字符串切割字符串为数组

match() 使用正则表达式与字符串相比较,返回一个包含匹配结果的数组

search() 对正则表达式或指定字符串进行搜索,返回第一个出现的匹配项的下标

replace() 用正则表达式和字符串进行比较,然后用新的子串替换被匹配的子串

split() 方法

split()方法用来将字符串转换为数组,它的参数可以是正则表达式,表示按一定的“模式”来进行字符串

的切割。

比如题目:按空格切割字符串“aa bbb c dd eeeeee”。

这个问题的难点是:如果书写 splice(" ")这样的写法切割字符串,那么将精确地按“一个空格”当做切

割依据,会产生很多不需要的空字符串。我们实际上需要的是按“不定量的空格”当做切割依据,必须使用正则

表达式来解决这个问题:

var str = "aa bbb c dd eeeeee";

var arr = str.split(/\s+/);

console.log(arr);

正则表达式中\s 匹配一个空白字符,加号“+”表示尽可能多的连续匹配空白字符,术语上称正则表达式的

匹配是“贪婪的”。

match() 方法

match()用来在字符串中寻找符合某种模式的子字符串,它的参数是正则表达式,返回匹配结果数组。

例如题目:在“abbcccbbbbbddbbbdabbb”中查询所有重复的“b”字符串。

题目中“重复的‘b’字符串”就是一种模式,使用字符串的 match()方法结合正则表达式可以实现题目要

求:

var str = "abbcccbbbbbddbbbdabbb";

var arr = str.match(/b+/);

console.log(arr);

match()方法返回的结果是一个数组,如图 7-18 所示。这个数组中下标为 0 的项是查询到的符合模式的子

字符串,下标为 1 的项是此子字符串在原字符串中的下标,下标为 2 的项是原字符串本身。

如果查询需要在全局进行,而不是找到第一个符合模式的子字符串就结束,此时需要给正则表达式添加一个

全局界定符“g”,g 的书写位置在正则表达式的斜杠后面。

var str = "abbcccbbbbbddbbbdabbb";

var arr = str.match(/b+/g);

console.log(arr);

search() 方法

search()方法返回字符串中第一个匹配模式的子字符串的下标位置。

例如题目:在字符串“abc12ef66g”中寻找数字首次出现的下标。

var str = "abc12ef66g";

var idx = str.search(/\d/);

console.log(idx); //3

控制台将输出 3,因为字符串 str 中下标为 3 的位置是第一个数字字符出现的位置。

如果字符串中找不到符合模式的子字符串,则 search()方法将返回-1。所以,search()方法通常用来字

符串中是否拥有某种字符,即验证 search()的结果是不是-1,至于出现的具体下标位置,通常程序员是不关心

的。

需要注意的是,search()方法会忽视全局界定符 g,它只会找到第一个符合模式的子字符串的下标位置输

出。例如:

var str = "abc12ef66g";

var idx = str.search(/\d/g);

console.log(idx); //3

控制台中仍将输出 3,可见 search()方法的正则表达式参数加上 g 符号是没有用的。

replace() 方法

replace()方法用来将字符串中符合模式的子字符串替换为指定字符串。

例如,将字符串“我爱足球,足球是我喜欢的运动”中的“足球”替换为“篮球”。

我们试着这样书写程序:

"我爱足球,足球是我喜欢的运动".replace("足球","篮球");

这条语句的功能是将字符串中出现的“足球”替换为“篮球”,它能够实现效果么?

replace()方法仅替换第一次出现的“足球”字样,第二个“足球”没有被替换成功。

解决方法就是使用正则表达式:

"我爱足球,足球是我喜欢的运动".replace(/足球/g,"篮球");

再比如题目:去掉字符串“aa b c d e f ”中的所有空格。

程序如下:

"aa b c d e f ".replace(/\s+/g , "");

正则表达式用\s 表示空格,加号“+”表示进行贪婪匹配,匹配至少一项