欢迎光临
我们一直在努力

JavaScript | 正则表达式基础

文章目录

定义

正则表达式是一门简单语言的语法规范,是强大、高效、便捷的文本处理工具,它能应用在一些方法中,从而实现对字符串中的信息实现查找、替换和提取操作。

Perl写法

正则表达式字面量写法,也叫作Perl写法,原因是JavaScript的正则表达式特性借鉴于Perl。正则表达式字面量定义为在一对 / 之间的字符,并且可以设置三个标志。

var expression = /pattern/flags;

正则表达式共有三个标志(flages):

  • g :表示全局模式,即模式将会被应用于所有的字符串,而非在发现第一个匹配项时立即停止
  • i:表示不区分大小写模式,即在匹配时忽略字符串的大小写
  • m:表示多行匹配模式,即在到达一行文本末尾时还会继续查找下一行中是否存在与模式匹配的项
//匹配字符串所有'at'的实例
var p = /at/g;
//test()方法返回一个布尔值表示是否可以找到匹配项
console.log(p.test('ata'));//true
console.log(p.test('aba'));//false

RegExp构造函数

和普通的内置对象一样,RegExp正则表达式对象也支持new RegExp()构造函数的形式。RegExp构造函数可以接收两个参数,分别是要匹配的字符串模式(pattern)和可选的标志字符串(flags),标志字符串可以选择不写。

RegExp构造函数的两个参数都是字符串。

//匹配字符串所有'at'的实例
var p = /at/g;
//test()方法返回一个布尔值表示是否可以找到匹配项
console.log(p.test('ata'));//true
console.log(p.test('aba'));//false

兼容问题

ECMAScript3规范规定,一个正则表达式直接量会在执行到它是转换为一个RegExp对象,同一段代码所表示的正则表达式直接量的每次运算都返回同一个对象

ECMAScript5规范则不同,同一段代码所表示的正则表达式直接量的每次运算都会返回新对象,IE6-8一直是按照ECMAScript5实现的。

由于正则表达式字面量并不支持变量,所以如果正则表达式中出现变量只能使用RegExp构造函数以字符串拼接的形式,将变量拼接到RegExp构造函数的参数中。

实例方法

RegExp对象的实例方法共5个,分为两类。包括toString()、toLocalString()、valueOf()这3种对象通用方法和test()、exec()正则匹配方法

对象通用方法

RegExp对象继承了Object对象的通用方法toString()、toLocaleString()、valueOf()这三个方法

【toString()】

toString()方法返回正则表达式的字面量

【toLocaleString()】

toLocaleString()方法返回正则表达式的字面量

【valueOf()】

valueOf()方法返回返回正则表达式对象本身

注意:不论正则表达式的创建方式是哪种,这三个方法都只返回其字面量形式

var pattern = new RegExp('[bc]at','gi');
console.log(pattern.toString()); // '/[bc]at/gi'
console.log(pattern.toLocaleString()); // '/[bc]at/gi'
console.log(pattern.valueOf()); // /[bc]at/gi
var pattern = /[bc]at/gi;
console.log(pattern.toString()); // '/[bc]at/gi'
console.log(pattern.toLocaleString()); // '[bc]at/gi'
console.log(pattern.valueOf()); // /[bc]at/gi

正则匹配方法

正则表达式RegExp对象的正则匹配方法只有两个:分别是exec()和test()

【exec()】

exec()方法专门为捕获组而设计,接受一个参数,即要应用模式的字符串。然后返回包含匹配项信息的数组,在没有匹配项的情况下返回null

在匹配项数组中,第一项是与整个模式匹配的字符串,其他项是与模式中的捕获组匹配的字符串,如果模式中没有捕获组,则该数组只包含一项

返回的数组包含两个额外的属性:index和input。index表示匹配项在字符串的位置,input表示应用正则表达式的字符串

var text = 'mom and dad and baby and others';
var pattern = /mom( and dad( and baby)?)?/gi;
var matches = pattern.exec(text);
console.log(pattern,matches);
//pattern.lastIndex:20
//matches[0]:'mom and dad and baby'
//matches[1]:' and dad and baby'
//matches[2]:' and baby'
//matches.index:0
//matches.input:'mom and dad and baby and others'   

对于exec()方法而言,即使在模式中设置了全局标志(g),它每次也只会返回一个匹配项。在不设置全局标志的情况下,在同一个字符串上多次调用exec(),将始终返回第一个匹配项的信息;而在设置全局标志的情况下,每次调用exec()都会在字符串中继续查找新匹配项

var text = 'cat,bat,sat,fat';
var pattern1 = /.at/;
var matches = pattern1.exec(text);
console.log(pattern1,matches);
//pattern1.lastIndex:0
//matches[0]:'cat'
//matches.index:0
//matches.input:'cat,bat,sat,fat'
var text = 'cat,bat,sat,fat';
matches = pattern1.exec(text);    
console.log(pattern1,matches);    
//pattern1.lastIndex:0
//matches[0]:'cat'
//matches.index:0
//matches.input:'cat,bat,sat,fat'
var text = 'cat,bat,sat,fat';
var pattern2 = /.at/g;
var matches = pattern2.exec(text);
console.log(pattern2,matches);    
//pattern2.lastIndex:3
//matches[0]:'cat'
//matches.index:0
//matches.input:'cat,bat,sat,fat'
var text = 'cat,bat,sat,fat';
matches = pattern2.exec(text);
console.log(pattern2,matches);    
//pattern2.lastIndex:7
//matches[0]:'bat'
//matches.index:4
//matches.input:'cat,bat,sat,fat'    

【tips】用exec()方法找出匹配的所有位置和所有值

var string = 'j1h342jg24g234j 3g24j1';
var pattern = /\d/g;
var valueArray = [];//值
var indexArray = [];//位置
var temp;
while((temp=pattern.exec(string)) != null){
    valueArray.push(temp[0]);
    indexArray.push(temp.index);  
}
//["1", "3", "4", "2", "2", "4", "2", "3", "4", "3", "2", "4", "1"] [1, 3, 4, 5, 8, 9, 11, 12, 13, 16, 18, 19, 21]
console.log(valueArray,indexArray); 

【test()】

test()方法用来测试正则表达式能否在字符串中找到匹配文本,接收一个字符串参数,匹配时返回true,否则返回false

var text = '000-00-000';
var pattern = /\d{3}-\d{2}-\d{4}/;
if(pattern.test(text)){
    console.log('The pattern was matched');
}

同样地,在调用test()方法时,会造成RegExp对象的lastIndex属性的变化。如果指定了全局模式,每次执行test()方法时,都会从字符串中的lastIndex偏移值开始尝试匹配,所以用同一个RegExp多次验证不同字符串,必须在每次调用之后,将lastIndex值置为0

var pattern = /^\d{4}-\d{2}-\d{2}$/g;
console.log(pattern.test('2016-06-23'));//true
console.log(pattern.test('2016-06-23'));//false
//正确的做法应该是在验证不同字符串前,先将lastIndex重置为0
var pattern = /^\d{4}-\d{2}-\d{2}$/g;
console.log(pattern.test('2016-06-23'));//true
pattern.lastIndex = 0;
console.log(pattern.test('2016-06-23'));//true

前面介绍过,javascript有9个用于存储捕获组的构造函数属性,在调用exec()或test()方法时,这些属性会被自动填充

注意:理论上,应该保存整个表达式匹配文本的RegExp.$0并不存在,值为undefined

if(/^(\d{4})-(\d{2})-(\d{2})$/.test('2016-06-23')){
    console.log(RegExp.$1);//'2016'
    console.log(RegExp.$2);//'06'
    console.log(RegExp.$3);//'23'
    console.log(RegExp.$0);//undefined
}
赞(0) 打赏
未经允许不得转载:散人研 » JavaScript | 正则表达式基础
分享到: 更多 (0)

评论 抢沙发

5 + 2 =
  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏