8.2 定义正则表达式
定义正则表达式的方法包括构造法和直接量,下面分别进行介绍。
8.2.1 构造正则表达式
JavaScript通过内置的RegExp对象实现对正则表达式的支持。RegExp是Regular Expression(规则表达式)短语的简写,它表示正则表达式的意思。
RegExp对象是一个构造函数,该函数可以带一个或两个参数,用来构造正则表达式。第一个参数指定了正则表达式的匹配模式,第二个参数为可选参数,用来修饰或限制匹配模式,即指定执行匹配操作的方式。
【示例1】先看一个简单的示例。
var r=new RegExp("a"); //构造最简单的正则表达式
这是一个最简单的正则表达式,匹配模式为一个字符"a",即该正则表达式能够匹配指定字符串中的字符"a"。由于没有修饰词(即没有设置第二个参数),所以这个正则表达式只能够匹配字符串中第一个小写字母a。
var s="javascript! =JAVA"; //定义字符串直接量 var a=s.match(r); //调用正则表达式执行匹配操作,返回匹配的数组 alert(a); //返回数组["a"] alert(a.index); //返回值为1
上面示例定义的正则表达式仅能够匹配字符串"javascript! =JAVA"中下标为1的字符a,后面的字母a将无法被匹配到。
【示例2】如果希望该正则表达式匹配字符串中所有的字母a,且不区分大小写,则可以在第二个参数中增加g和i修饰词。
var r=new RegExp("a", "gi"); //设置匹配模式为全局匹配,且不区分大小写
然后测试:
var s="javascript! =JAVA"; //字符串直接量 var a=s.match(r); //匹配查找 alert(a); //返回数组["a", "a", "A", "A"]
提示:在正则表达式中,JavaScript主要支持“g”、“i”和“m”3个修饰性字符。具体说明如下。
字符“g”是global(全局)一词的缩写,即用来指定全局匹配,通俗地说就是正则表达式将在指定字符串范围内执行所有匹配查找,而不是仅仅找到第一个匹配后就立即停止检索。
字符“i”是case-insensitive(大小写不敏感)短语中insensitive一词的缩写,即执行不区分大小写的匹配,也就是说对于字母大小写视为等同。
字符“m”是multiline(多行)一词的缩写,即设置匹配模式能够在多行字符串中执行操作。
这3个修饰词分别指定了匹配操作的范围、大小写和多行行为。这些关键词可以自由组合,以字符串的形式传递给Regular()构造函数。
在ECMAScript标准化之前,JavaScript不支持m修饰词,后来才提供支持。另外,JavaScript不支持的修饰词包括x(设置空格匹配问题)、e(设置逆向匹配问题)、s(设置点号匹配问题)等。
【示例3】RegExp()构造函数的第一个参数是一个字符串或者一个正则表达式,该参数构成了正则表达式的匹配主体。如果该参数是一个字符串,则可以是一个符合正则表达式规则的字符串。
var r=new RegExp("\\b\\w", "gi"); //构造正则表达式对象 var s="javascript JAVA"; //字符串直接量 var a=s.match(r); //匹配查找 alert(a); //返回数组["j", "J"]
在上面示例中,字符串"\\b\\w"是一个匹配模式,其中反斜杠表示转义序列,双反斜杠表示斜杠本身的意思,而\b又表示单词的边界,\w表示任意ASCII字符,所以上面的正则表达式将匹配字符串"javascript JAVA"中每个单词的首字母。
因为无论是字符串直接量,还是正则表达式都使用字符\表示转义序列,所以将正则表达式作为字符串直接量传递给RegExp()构造函数时,必须使用“\\”替换所有“\”字符。
提示:当要动态创建一个正则表达式,而不能使用正则表达式直接量的语法来表示时,构造函数RegExp()非常有用。例如,如果检索的字符串是由用户输入的,那么就必须在运行时使用RegExp()构造函数来创建正则表达式。
【示例4】如果RegExp()构造函数的第一个参数是一个正则表达式,则第二个参数可以省略。这时RegExp()构造函数将使用与正则表达式参数相同的匹配模式和修饰词创建一个新的RegExp对象。
var r=new RegExp("\\b\\w", "gi"); //构造正则表达式对象 var r1=new RegExp(r); //把正则表达式变量作为参数传递给RegExp()构造函数 var s="javascript JAVA"; //字符串直接量 var a=s.match(r); //匹配查找 alert(a); //返回数组["j", "J"]
可以把正则表达式直接量传递给RegExp()构造函数,对正则表达式进行类型封装。
【示例5】RegExp()可以作为普通函数进行调用。作为普通函数,RegExp()函数的行为与使用new运算符调用构造函数时一样。不过如果函数的参数是正则表达式,那么它仅返回正则表达式,而不再创建一个新的RegExp对象。
var a=new RegExp("\\b\\w", "gi"); //构造正则表达式对象 var b=new RegExp(a); //对正则表达式对象进行再封装 var c=RegExp(a); //返回正则表达式直接量 alert(a.constructor==RegExp); //返回true alert(b.constructor==RegExp); //返回true alert(c.constructor==RegExp); //返回true
8.2.2 正则表达式直接量
JavaScript约定在正则表达式直接量中,双斜杠包含的字符为正则表达式的匹配模式,它是一组特殊的字符串,但是不能够使用引号进行包含。正则表达式的修饰词则跟随在最后一个斜杠的后面。
【示例1】在下面代码中定义一个正则表达式直接量,然后就直接进行调用。
var r =/\b\w/gi; var s = "javascript JAVA"; var a=s.match(r); //直接调用正则表达式直接量 alert(a); //返回数组["j", "J"]
提示:在RegExp()构造函数与正则表达式直接量语法中,匹配模式的表示是不同的。对于RegExp()构造函数来说,它接收的是字符串,而不是正则表达式的匹配模式。所以,在上面示例中,RegExp()构造函数中第一个参数中的特殊字符必须使用双反斜杠来表示,以防止字符串中每个字符被RegExp()构造函数转义。同时对于第二个参数中的修饰词也应该使用引号来包含。而正则表达式直接量中,每个字符都按正则表达式的规则来定义,普通字符与特殊字符都会被正确解释。
【示例2】在RegExp()构造函数中可以为正则表达式传递变量,而在正则表达式直接量中是不允许的。
var r=new RegExp("a"+s+"b", "g"); //动态创建正则表达式 var r=/"a"+s+"b"/g; //错误的用法
在上面示例中,对于正则表达式直接量来说,“"”和“+”都将被视为普通字符而进行匹配,而不是作为字符与变量的语法标识符进行连接操作。