正则表达式就是一个字符模式。和String对象类似,在JavaScript中正则表达式也是一个对象,它主要用于字符串的模式匹配。创建正则表达式有两种方式:隐式创建(文字量方法)和显示创建(使用构造函数)。
隐式创建正则表达式
使用隐式方法创建正则表达式的方法为:将文字量的正则表达式赋值给一个变量。正则表达式是包含在两个斜杠之间的一个或多个字符,在后一个斜杠的后面,可以指定一个或多个选项。隐式创建正则表达式的语法为:
var regExp = /pattern/flags
其中,“pattern”为指定的匹配模式,flags为0个或多个可选项,这些选项及其含义如下:
i
:表示忽略大小写,就是在字符串匹配的时候不区分大小写。g
:表示全局匹配,即匹配字符串中出现的所有模式。m
:表示进行多行匹配。ECMAScript标准化之前,不支持m
属性。如果pattern是正则表达式,而不是字符串,则必须省略该参数。
例如下面的正则表达式都是有效的正则表达式:
var regExp1 = /abc/; var regExp2 = /abc/gi; var regExp3 = /^JavaScript/; var regExp4 = /0[0-9][0-9]*/; var regExp5 = /\binter/i;
显示创建正则表达式
显示的创建正则表达式是通过构造函数RegExp()
来实现。构造函数RegExp()
中有2个参数:第一个参数指定正则表达式,这是正则表达式的字符串表示方法,例如:“abc”表示隐式创建中的/abc/
,第二个参数是可选参数,它指定正则表达式的选项,它的标记字符和隐式创建时的相同,意义也相同。显示创建正则表达式的语法为:
var regExp = new RegExp("pattern","flags");
正则表达式对象的方法
正则表达式对象RegExp
提供了两个可用的方法:test()
和exec()
。
test()方法
test()
方法的功能为:测试字符串中是否包含了匹配该正则表达式的子串,如果包含了这样的子串,那么返回true
,否则返回false
。
在使用test()
方法完成检测之后,RegExp
对象的lastIndex
属性包含了下一次字符串搜索的开始位置。如果进行全局搜索,那么lastIndex
属性的值是最后一个匹配字符串后面一个字符的位置。来看下面的例子:
var mystring = "hello regExp!"; var regexp = /reg/i; if(regexp.test(mystring)){ alert("找到了指定模式的字符串"); }else{ alert("没有找到指定模式的字符串"); }
在这个例子中,使用正则表达式/reg/i
来测试mystring字符串中是否包含匹配的模式子串,匹配时不区分大小写。得到的结果为true
,所以会显示“找到了指定模式的字符串”。
exec()方法
exec()
方法的功能非常强大,它是一个通用的方法,而且使用起来也比test()
方法以及支持正则表达式的String对象的方法更为复杂。
exec()
的功能为:在字符串中进行匹配搜索,并将结果保存在一个数组中返回,如果没有找到子串,那么返回null。
exec()
方法在功能上与String对象的match()
方法类似,它使用正则表达式指定的匹配模式搜索字符串,从中找到匹配的子串。没有找到子串时该方法返回null
,否则会返回一个增强的数组对象(Array Object)。该数组中包含了匹配的子串。当我们需要知道匹配字符串的开始位置和匹配字符串是否多次出现时,应该使用这个方法。
当执行exec
方法后,正则表达式对象的lastIndex
属性的值为前一次匹配字符串后面的第一个字符的位置(从0开始计数)。使用这个特性,我们使用迭代和提取字符串方法,可以得到字符串中与正则表达式相匹配的所有子串。
下面是一个使用exec()
方法的简单例子:
var mystring = "abc 123 def 456 ghj"; var regexp = new RegExp("123"); regexp.exec(mystring);
exec()
方法返回的数组对象有一个扩展属性(普通数组中没有这个属性),这个属性是index
,它给出了匹配字符串的开始位置。此外,该数组还有另外一个扩展属性input
,它给出了被搜索的字符串。
另外,返回的数组中,第0个元素是与正则表达式相匹配的文本,第1个元素是与正则表达式对象的第1个子表达式相匹配的文本(如果有的话),第2个元素是与正则表达式对象的第2个子表达式相匹配的文本(如果有的话),以此类推。
提示:如果在一个字符串中完成了一次模式匹配之后要开始检索新的字符串,就必须手动地把 lastIndex 属性重置为 0。
另外,无论 RegExpObject 是否是全局模式,exec()都会把完整的细节添加到它返回的数组中。这就是exec()与String.match()的不同之处,后者在全局模式下返回的信息要少得多。因此我们可以这么说,在循环中反复地调用exec() 方法是唯一一种获得全局模式的完整模式匹配信息的方法。
在下面的例子中,演示了exec()
的使用方法,并给出了该方法返回数组的内容和几个属性的取值。
var mystring = "aaa 111 bbb 222 ccc 1111 222ddd"; var regexp = /111/g; var array = regexp.exec(mystring); if(array){ var str = "找到了匹配子串!" +"\n返回数组的值为: "+array +"\n数组元素个数为: "+array.length +"\n被搜索的字符串为: "+array.input +"\n匹配子串的开始位置为: "+array.index +"\n匹配子串后面第一个字符的位置为: "+regexp.lastIndex; alert(str); }else{ alert("没有找到匹配的子串!"); }
执行上面的代码,得到下面的返回结果:
正则表达式对象的属性
正则表达式对象包含两类属性:类属性和实例属性。类属性也叫作静态属性,例如input
是RegExp对象的一个属性,它包含了最近一次进行匹配操作的字符串。这个属性使用格式RegExp.input
进行访问,它属于类属性。下表中列出了所有的类属性及其含义:
类属性 | 含义 |
input | 给出了正则表达式要匹配的字符串。在调用exec() 或test() 方法时,如果没有给出要搜索的字符串参数,那么就使用这个属性作为被搜索的字符串,该属性的另外一个名称是$_ |
lastMatch | 最近一次匹配的字符,该属性的另外一个名字是$& |
lastParen | 保存匹配结果最后一个子匹配的内容(最后一个括号的匹配内容),该属性的另外一个名称是$+ |
leftContext | 最近一次匹配的字符串左边所有字符组成的子串,该属性的另外一个名称是$` |
rightContext | 最近一次匹配的字符串右边所有字符组成的子串,该属性的另外一个名称是$' |
$1,$2,$3,...,$9 | 保存了与正则表达式中括号内子模式相匹配的子串 |
实例属性是正则表达式对象的属性,它通常与存储正则表达式的变量相关联。下表中列出了所有的正则表达式实例属性。
实例属性 | 含义 |
global | Boolean值,指明正则表达式是否选择了g 选项,true为选中,fasle为未选中 |
ignoreCase | Boolean值,指明正则表达式是否选择了i 选项,true为选中,fasle为未选中 |
lastIndex | 选择g 选项后,该属性指明执行exec() 或test() 方法后最后一次匹配字符串后面第一个字符的位置 |
source | 只读属性,给出了正则表达式的内容,即除了斜杠和选项字符之外的整个正则表达式。 |
multiline | Boolean值,指定搜索字符串时是否跨行搜索,true为跨行搜索,false为不跨行,该属性的另外一个名称是$* |
下面是一个使用正则表达式属性的例子,查看它的返回结果,可以更好的理解正则表达式的属性。
var mystring = "时间是一切财富中最宝贵的财富。——德奥弗拉斯多"; var regexp = /财富/g; var booleanResult = regexp.test(mystring); if(booleanResult){ document.write("测试的正则表达式的内容为: "+regexp.source +"<br>测试的结果为: "+booleanResult); document.write("<br>下一次搜索开始的位置是: "+regexp.lastIndex +"<br>搜索的字符串为: "+RegExp.input); document.write("<br>最近一次匹配的字符为: "+RegExp.lastMatch); document.write("<br>最近一次匹配的字符前面的子串为: "+RegExp.leftContext); document.write("<br>最近一次匹配的字符后面的子串为: "+RegExp.rightContext); document.write("<br>正则表达式是否跨行搜索: "+regexp.multiline); document.write("<br>正则表达式是否选用了i选项: "+regexp.ignoreCase); document.write("<br>正则表达式是否选用了g选项: "+regexp.global); }
执行上面的代码,我们得到下面的结果:
测试的正则表达式的内容为: 财富 测试的结果为: true 下一次搜索开始的位置是: 7 搜索的字符串为: 时间是一切财富中最宝贵的财富。——德奥弗拉斯多 最近一次匹配的字符为: 财富 最近一次匹配的字符前面的子串为: 时间是一切 最近一次匹配的字符后面的子串为: 中最宝贵的财富。——德奥弗拉斯多 正则表达式是否跨行搜索: false 正则表达式是否选用了i选项: false 正则表达式是否选用了g选项: true