JS编程建议——42:用好正则表达式静态值

建议42:用好正则表达式静态值
正则表达式的静态属性比较特殊,有两个名字:长名(全称)和短名(简称,以美元符号开头表示),详细说明见表2.1。
表2.1 RegExp的静态属性
长名 短名 说明
input $_ 最后用于匹配的字符串,即传递给exec()或test()方法的字符串
lastMatch $& 最后匹配的字符
lastParen $+ 最后匹配的分组
leftContext $` 在上次匹配之前的子字符串
multiline $* 用于指定是否所有表达式都使用多行模式的布尔值
rightContext $' 在上次匹配之后的子字符串
在下面的这个示例中借助正则表达式的静态属性,匹配字符串“Javascript”,不区分大小写:
var s = "Javascript,not Javascript";
var r = /(Java)Script/gi;
var a = r.exec(s);
alert(RegExp.input); //"Javascript,not Javascript"
alert(RegExp.leftContext); //空字符串,因为在第一次匹配操作时,左侧没有内容
alert(RegExp.rightContext); //",not Javascript"
alert(RegExp.lastMatch); //"Javascript "
alert(RegExp.lastParen); //"Java"
上面示例演示了正则表达式的几个静态属性的用法。
input属性实际上存储的是被执行匹配的字符串,即整个字符串“Javascript,not Javascript”。
leftContext属性存储的是执行第一次匹配之前的子字符串,这里为空,因为在第一次匹配时文本“Javascript”左侧为空,而rightContext属性存储的是执行第一次匹配之后的子字符串,即为“,not Javascript”。
lastMatch属性包含的是第一次匹配的子字符串,即为“Javascript”。
lastParen属性包含的是第一次匹配的分组,即为“Java”。如果模式中包含多个分组,则会显示最后一个分组所匹配的字符。例如:
var r = /(Java)(Script)/gi;
var a = r.exec(s); //执行匹配操作
alert(RegExp.lastParen); //返回"Script",而不再是"Java"
也可以使用短名来读取这些属性所包含的值,考虑到这些短名不符合JavaScript语法规范,因此必须使用中括号运算符来进行读取操作。不过对于$_属性来说,由于它符合JavaScript标识符语法规范,因此可以直接使用。例如,针对上面示例也可以这样设计:
var s = "Javascript,not Javascript";
var r = /(Java)(Script)/gi;
var a = r.exec(s);
alert(RegExp.$_); //"Javascript,not Javascript"
alert(RegExp["$`"]); //空字符串
alert(RegExp["$'"]); //",not Javascript"
alert(RegExp["$&"]); //"Javascript "
alert(RegExp["$+"]); //"Java"
这些属性的值都是动态的,每次执行exec()或test()方法时,所有属性值都会被重新设置。当在下面示例中执行第一次匹配和第二次匹配时,这些静态属性值都会实时动态更新。
var s = "Javascript,not Javascript";
var r = /Scrip(t)/gi; // 第一次定义的匹配模式
var a = r.exec(s); // 执行第一次匹配
alert(RegExp.$_); //"Javascript,not Javascript"
alert(RegExp["$`"]); //"Java"
alert(RegExp["$'"]); //",not Javascript"
alert(RegExp["$&"]); //"Script"
alert(RegExp["$+"]); //"t"
var r = /Jav(a)/gi; // 第二次定义的匹配模式
var a = r.exec(s); // 执行第二次匹配
alert(RegExp.$_); //"Javascript,not Javascript"
alert(RegExp["$`"]); //空字符串
alert(RegExp["$'"]); //"Script,not Javascript"
alert(RegExp["$&"]); //"Java"
alert(RegExp["$+"]); //"a"
通过上面的示例可以看出,RegExp对象的静态属性是公共的,对于所有正则表达式来说是可以共享的,因此这些静态属性的值也是实时变化的。
multiline属性与上面几个属性不同,它不会根据每次执行的操作进行实时更新,并且还可以控制所有正则表达式的m标志项。例如:
var s = "anbnc";
var r = /w+$/g; // 定义匹配模式
var a = s.match(r); // 执行默认匹配,返回数组["c"]
RegExp.multiline = true; // 动态设置模式为多行匹配
var a = s.match(r); //["a", "b", "c"]
提示:IE和Opera浏览器不支持RegExp.multiline属性,考虑到浏览器的兼容性,不建议读者使用这种动态方式设置正则表达式的多行匹配模式。

时间: 2024-08-28 19:58:27

JS编程建议——42:用好正则表达式静态值的相关文章

JS编程建议——38:正确认识正则表达式工作机制

建议38:正确认识正则表达式工作机制有很多因素影响正则表达式的效率.首先,正则表达式适配的文本千差万别,部分匹配时比完全不匹配所用的时间要长.其次,每种浏览器的正则表达式引擎也有不同的内部优化.要有效使用正则表达式,重要的是理解它们的工作机制.一个正则表达式处理的基本步骤如下:第1步,编译.在创建了一个正则表达式对象后,浏览器先要检查模板有没有错误,然后将它转换成一个本机代码例程,用于执行匹配工作.如果将正则表达式赋给一个变量,就可以避免重复执行此步骤.第2步,设置起始位置.当一个正则表达式投入

JS编程建议——48:慎用正则表达式修剪字符串

建议48:慎用正则表达式修剪字符串(1)使用两个子表达式修剪字符串去除字符串首尾的空格是一个简单而常见的任务,但到目前为止JavaScript 还没有实现它.正则表达式允许用很少的代码实现一个修剪函数,最好的全面解决方案可能是使用两个子表达式:一个用于去除头部空格,另一个用于去除尾部空格.这样处理简单而快速,特别是处理长字符串时.if(!String.prototype.trim) { String.prototype.trim = function() { return this.replac

JS编程建议——46:提高正则表达式执行效率

建议46:提高正则表达式执行效率(1)关注如何让匹配更快失败正则表达式处理慢往往是因为匹配失败过程慢,而不是匹配成功过程慢.使用正则表达式匹配一个很大字符串的一小部分,情况更为严重,正则表达式匹配失败的位置比匹配成功的位置要多得多.一个修改使正则表达式匹配更快但失败更慢,例如,通过增加所需的回溯次数尝试所有分支的排列组合,这通常是一个失败的修改.(2)正则表达式以简单的.必需的字元开始最理想的情况是,一个正则表达式的起始字元应当尽可能快速地测试并排除明显不匹配的位置.用于此目的好的起始字元通常是

JS编程建议——41:正确使用正则表达式引用

建议41:正确使用正则表达式引用正则表达式在执行匹配运算时会自动把每个分组(子表达式)匹配的文本都存储在一个特殊的地方以备将来使用.这些存储在分组中的特殊值被称为反向引用.反向引用将遵循从左到右的顺序,根据表达式中左括号字符的顺序进行创建和编号.var s = "abcdefghijklmn";var r = /(a(b(c)))/;var a = s.match(r); //["abc", "abc" , "bc" , &q

JS编程建议——47:避免使用正则表达式的场景

建议47:避免使用正则表达式的场景正则表达式匹配速度是非常快的.然而,当只搜索文字字符串时正则匹配经常会显得多余,尤其当事先知道了字符串的哪一部分将要被测试时.例如,要检查一个字符串是不是以分号结束,可以使用:endsWithSemicolon = /;$/.test(str);当前没有哪个浏览器"聪明"到这个程度,能够意识到这个正则表达式只能匹配字符串的末尾.最终它们所做的将是一个一个地测试整个字符串.每当发现了一个分号,正则表达式就前进到下一个字元($),检查它是否匹配字符串的末尾

JS编程建议——40:正确使用正则表达式分组(2)

建议40:正确使用正则表达式分组(2)当然,并不限制在分组后使用星号,还可以使用任意重复类数量词: var r = /(abcdef-?){5}/; // 连续匹配5次子表达式 var r = /(abcdef-?){1,5}/; // 最多匹配5次子表达式 var r = /(abcdef-?){0,}/; // 匹配任意次子表达式 var r = /(abcdef-?)?/; // 最多匹配一次子表达式 var r = /(abcdef-?)+/; // 最小匹配一次子表达式 如果混合使用字

JS编程建议——3:减少全局变量污染

建议3:减少全局变量污染定义全局变量有3种方式:在任何函数外面直接执行var语句. var f = 'value'; 直接添加一个属性到全局对象上.全局对象是所有全局变量的容器.在Web浏览器中,全局对象名为window. window.f = 'value'; 直接使用未经声明的变量,以这种方式定义的全局变量被称为隐式的全局变量. f = 'value'; 为方便初学者在使用前无须声明变量而有意设计了隐式的全局变量,然而不幸的是忘记声明变量成了一个非常普遍的现象.JavaScript的策略是让

JS编程建议——8:谨慎使用运算符(1)

建议8:谨慎使用运算符(1)1.用===,而不用==JavaScript有两组相等运算符:===和!==.==和!=.===和!==这一组运算符会按照期望的方式工作.如果两个运算数类型一致且拥有相同的值,那么===返回true,而!==返回false.==和!=只有在两个运算数类型一致时才会做出正确的判断,如果两个运算数是不同的类型,会试图强制转换运算数的类型.转换的规则复杂且难以记忆,具体规则如下: '' == '0' // false 0 == '' // true 0 == '0' //

JS编程建议——14:不要滥用eval

建议14:不要滥用evaleval是一个被滥用得很严重的JavaScript特性.eval函数传递一个字符串给JavaScript编译器,该字符串会被当成一段 JavaScript 程序来解析和执行.很多开发者对JavaScript语言一知半解,却喜欢使用eval.例如,如果只知道点表示法,却不知道下标表示法,就会按如下方法编写代码: eval("value = obj." + key + ";"); 而不是按如下方法编写: value = obj[key]; 使用