正则表达式的定义
正则表达式(regular expression)是一种适用于字符串的模式匹配的语言,其应用领域主要集中在搜索和替换 。 字符串的模式匹配的一个具体实例是从"I LOVE YOU!"这个字符串中找到"LOVE"这个特定的字符串。当然,这个例子比较简单,完全不需要使用正则表达式。然而,如果要是在"I LOVE YOU!"这个字符串中检索从第一个O开始到第二个O结束的字符串时,该如何实现。此时用正则表达式就会带来极大得方便。 正则表示式既然是一种语言,那么也就有其自身的语法。如果我们从语言的角度来看,将正则表达式看作是一种专门为了模式匹配而设计的表达方式理解起来会更容易些。
接下来的教程需要一定正则表达式的基础。请没有基础的同志们,先认真看下
正则表达式30分钟入门教程。请耐下心来,先把基础打好。
JavaScript 正则表达式的语法
下表列举了些在 ECMAScript第五版(JS 是一种符合
ECMAScript标准的程序设计语言)中定义的正则表达式元字符:
粗看这表,会感觉信息量比较大,需要记的元字符比较多。不要怕,冷静下来,仔细观察,你就会发现其中有规律可循。比如,
大小写相反或者相差?的元字符,表示的意义相反。还有特殊的字母可如下记忆:s为space的首字母,w为word的首字母,d为double的首字母,b为border的首字母。还有{}里面代表的数字代表范围;|代表或;*代表0次或更多次,即1乘以自然数的范围;+代表1次或更多次,即1加上自然数的范围。 如果不希望让元字符中存在的字符被解释为元字符,则
需要通过反斜杠字符\对其进行转义。例如:对点字符.进行匹配,则要写成\.的形式。 如果在模式中要匹配反斜杠字符,则
需要将其写成\\。
元字符 | 说明 |
---|---|
. | 任意1个字符 |
\s | 空白字符 |
\S | 非空白字符 |
\w | 可以构成单词的字符(包括字母、数字、下划线以及汉字) |
\W | 不能构成单词的字符 |
\d | 数字 |
\D | 非数字 |
\b | 单词的边界 |
\B | 不是单词的边界 |
^ | 行首 |
$ | 行末 |
X? | 字符X重复出现0次或1次 |
X?? | 字符X重复出现0次或1次(非贪心法,即尽可能寻找出现次数较少的情况) |
X* | 字符X重复出现0次或更多次 |
X*? | 字符X重复出现0次或更多次(非贪心法) |
X+ | 字符X重复出现1次或更多次 |
X+? | 字符X重复出现1次或更多次(非贪心法) |
X{n} | 字符X重复出现n次 |
X{n}? | 字符X重复出现n次(非贪心法) |
X{n,} | 字符X重复出现n次或更多次 |
X{n,}? | 字符X重复出现n次或更多次(非贪心法) |
X{n,m} | 字符X重复出现至少n次至多m次 |
X{n,m}? | 字符X重复出现至少n次至多m次(非贪心法) |
X|Y | X或Y |
[XYZ] | 1个是 X 或者 Y 或者 Z 的字符 |
[^XYZ] | 一个除了X、Y、Z以外的任意字符 |
(X) | 分组(已供之后应用) |
\数字 | 对分组的应用(这里的数字是分组出现的序号) |
(?:X) | 仅分组(即不记录分组的序号,也不捕获该分组) |
X(?=Y) | 匹配X之后接着Y的情况 |
X(?!Y) | 匹配X之后不接着Y的情况 |
JavaScript中的正则表达式
终于我们可以开始学习
如何在JavaScript中使用正则表达式了!有了之前的基础,接下来的学习就简单多了。 在JavaScript中,我们可以通过正则表达式对象来使用正则表达式。正则表达式对象是RegExp类的对象实例。 示例:
注:例子中使用了test的方法:如果输入字符串与模式匹配,,test方法就会返回真。 除了new方式外,还可以通过字面量的方式生成一个RegExp实例。如下图,通过在两个/(斜杠字符)之间书写正则表达式的模式。
在使用正则表达式的旗标时,如果是构造函数,将其传递给第二个参数,如果是字面量,则写在第二个斜杠字符之后。 示例:
如果有人对JavaScript的prototype机制不太理解,请看
Javascript继承机制的设计思想。
示例:
前面有稍微提到过分组,现在咱们来仔细谈谈正则表达式的是分组。 所谓
正则表达式的分组,指的是能够在正则表达式中引用匹配字符串中的子字符串(也称为前向引用)。简单地说,
就是能够被引用的子字符串就是一个分组。可以将模式中的一部分用原括号括起来进行分组。在一个模式中,可以多次使用圆括号分组。值得注意的是,
对于前向引用来说,分组号是从1开始计数的。 先看下面的示例:
在exec方法的返回值中,数组的第0个元素是在输入字符串中第一个得到匹配的字符串,而从数组的第1个元素起则是分组的前向引用的子字符串。 如果去除用于分组的圆括号,则会出现如下结果。
var reg = /^[0-9]/;
var reg = new RegExp('^[0-9]');
//以上两个语句等价
虽然以上两种生成方式没啥区别,不过
建议使用字面量方式,因为其书写更简洁优雅些。不过,如果需要对正则表达式字符串进行组合时,则还是得需要使用RegExp的构造函数调用。 注意:
通过JavaScript的字符串书写反斜杠字符时,必须对其进行转义。
//表示头部为空白字符的正则表达式的模式
var reg = /^\s+/;
//如果通过字符串来传递该模式,则需要对反斜杠字符进行转义
var reg = new RegExp('^\\s+');
当我们在匹配时,想指定全局匹配,或忽略英文字母的大小写,或多行匹配等规则时,我们就需要使用正则表达式的旗标flag了。例如:/forever/gi 会找出所有不区分大小写的forever 。
旗标 | 说明 |
---|---|
g | 全局匹配模式。 |
i | 忽略英文字母的大小写模式 |
m | 多行模式。^与$将对多行的行首与行末进行匹配 |
//设置全局匹配的旗标
var reg = /^[0-9]/g;
var reg = new RegExp('^[0-9]','g');
//设置多个旗标
var reg = /^[0-9]/gi;
var reg = new RegExp('^[0-9]','gi');
注:使用了全局旗标,会再多次调用 exec 方法时,不断地寻找下一个匹配。从内部来看,RegExp 对象的 lastIndex 属性的值会不断地更新,以供下次查找使用。 现在,再具体介绍下RegExp类。
函数或是构造函数调用 | 说明 |
---|---|
RegExp(pattern, flags) | 生成一个正则表达式模式为 pattern 的 RegExp 实例 |
new RegExp(pattern, flags) | 生成一个正则表达式模式为 pattern 的 RegExp 实例 |
属性名 | 说明 |
---|---|
prototype | 用于原形链,值为 /(?:)/ |
length | 值为2 |
属性名 | 说明 |
---|---|
constructor | 对 RegExp 类对象的引用 |
exec(string) | 返回对输入字符串 string 进行正则表达式匹配的结果 |
test(string) | 返回对输入字符串 string 进行正则表达式匹配的结果的布尔值 |
toString() | 将正则表达式转换为字符串形式。该字符串的格式为在/与/之间包含了相应的正则表达式 |
属性名 | 说明 |
---|---|
ignoreCase | 正则表达式的旗标之一(对应i) |
global | 正则表达式的旗标之一(对应g) |
lastIndex | 用于标记下一次匹配的起始位置的字符串的下标 |
multiline | 正则表达式的旗标之一(对应m) |
source | 正则表达式模式的字符串 |
再举个引用分组的小例子:
注:\数字 ,是对分组的引用。
字符串对象与正则表达式对象
平时,我们在使用正则表达式的时候,还常常会使用一些 String 对象的方法,在这些方法中,是以正则表达式对象作为参数。
属性名 | 说明 |
---|---|
match(regexp) | 返回正则表达式 regexp 的匹配结果,如果没有匹配的话则返回 -1。 |
replace(searchValue, replaceValue) | 将 searchValue (正则表达式或字符串值)替换为 replaceValue(字符串或函数),并返回相应的字符串 |
search(regexp) | 返回正则表达式 regexp 的匹配位置的下标 |
split(separator, limit) | 通过参数 separator (字符串或正则表达式)对字符串进行分割,并返回一个字符串值的数组 |
前向引用 | 说明 |
---|---|
$& | 相匹配的字符串 |
$数字 | 分组的前向引用。数字从1开始计 |
$` | 位于匹配之前的字符串(注:`是键盘左上角的那个键) |
$' | 位于匹配之后的字符串(注:'是单引号) |