JavaScript正则表达式RegExp

正则表达式,也称划定规矩表达式,经常运用其来完成对字符串的校验和过滤。由于正则表达式的灵活性、逻辑性和功能性都异常壮大,而且 能够运用很简朴的体式格局完成对庞杂字符串的掌握,所以许多程序言语都支撑正则表达式。在JavaScript中正则示意也异常壮大和有用。

基本情势

正则表达式(regular expression)是一种表达文本情势(即字符串组织)的要领,有点像字符串的模板,经经常使用作根据“给定情势”婚配文本的东西。比方,正则表达式给出一个Email地点的情势,然后用它来肯定一个字符串是不是为Email地点。JavaScript的正则表达式系统是参照Perl 5竖立的。

新建正则表达式有两种要领。一种是运用字面量,以斜杠示意最先和完毕。

// 字面量情势
var telRegex1 = /^1[3|5|7|8]\d{9}$/;
// 组织函数情势
var telRegex2 = new RegExp('^1[3|5|7|8]\\d{9}$');

以上都是建立了一个内容为^1[3|5|7|8]\d{9}$的正则表达式,其示意对一个手机号码的校验。必需以1最先,第二位为3/5/7/8,以后为9位数字。

这两种写法——字面量和组织函数——在运行时有一个纤细的区分。采纳字面量的写法,正则对象在代码载入时(即编译时)天生;采纳组织函数的要领,正则对象在代码运行时天生。考虑到誊写的方便和直观,现实运用中,基本上都采纳字面量的写法。

有一点须要注重,运用组织函数建立正则表达式时,传入的参数是字符串情势的,在字符串内部,\本身也是一个转义符,因而须要再运用一个\来对其举行正则表达式的转义。上面第二个示例中,\\d才代表恣意数字。

关于正则表达式中,种种标记的寄义,以及运用要领,请看背面的引见:

元字符

一些经常使用的元字符以下:

  • . 婚配除换行符以外的恣意字符

  • \w 婚配字母或数字或下划线或汉字

  • \s 婚配恣意的空白符

  • \d 婚配数字

  • \b 婚配单词的最先或完毕

  • ^ 婚配字符串的最先处

  • $ 婚配字符串的完毕处。

  • * 婚配前面的子表达式恣意次。

  • ? 婚配前面子表达式0次或一次,等价于{0, 1}

  • + 婚配之前子表达式一次到屡次,等价于{1, }

  • {n} 婚配之前的子表达式n次。

  • {m,n} 婚配之前的子表达式起码m次,最多n次。

  • {n, } 婚配之前的子表达式最少n次。

  • [xyz] 字符鸠合,示意个中恣意一个字符。示意局限可用-链接,比方[a-z] 示意a-z之间的恣意一个字母。还能够如许誊写[A-Za-z0-9]

  • [^xyz] 字符即可,示意非个中恣意一个字符。示意局限可用-链接,比方[^a-z] 示意非 a-z之间的恣意一个字母。

  • | 示意或(or)关联,比方 com|cn,示意婚配com或许cn。

  • () 用于分组,其分组中的内容可已由过程$1-$9按递次猎取(字符串相干要领中),以后的正则中也能够经由过程\1-\9举行援用(正则表达式内部)。(分组0示意悉数正则婚配内容或悉数正则表达式)

在正则表达式中,以上这些以及一些未列出的元字符都是有本身寄义的,假如我们须要婚配这些元字符本身,能够运用\对其举行转义即可。

更多元字符能够检察:正则表达式

属性

修饰符

  • ignoreCase:返回一个布尔值,示意是不是设置了i修饰符,该属性只读。

  • global:返回一个布尔值,示意是不是设置了g修饰符,该属性只读。

  • multiline:返回一个布尔值,示意是不是设置了m修饰符,该属性只读。

  • stickyES6返回一个布尔值,示意是不是设置了y修饰符,只读。

var r = /abc/igm;

r.ignoreCase; // true
r.global;  // true
r.multiline;  // true

婚配时属性

  • lastIndex:返回下一次最先搜刮的位置。该属性可读写,然则只在设置了g修饰符时有意义。

  • sourceES5返回正则表达式的字符串情势(不包含反斜杠),该属性只读。

  • flagsES6返回正则表达式中的修饰符。

var r = /abc/igm;

r.lastIndex; // 0
r.source; // "abc"
r.flags; //"igm"

要领

test()

正则对象的test对象吸收一个字符串,示意测试字符串,返回一个布尔值,示意是此字符串是不是满足婚配前提。

telRegex1.test('13612341234'); // true
telRegex2.test('13612341234'); // true
telRegex1.test('136123412'); // false

假如正则表达式带有g修饰符,则每一次test要领都从上一次完毕的位置最先向后婚配。同时,能够经由过程正则对象的lastIndex属性指定最先搜刮的位置。

var xReg = /x/g;
var str = 'xyz_x1_y1_x3';

xReg.lastIndex; // 0
xReg.test(str); // true

xReg.lastIndex; // 1
xReg.test(str); // true
xReg.lastIndex; // 5

// 指定位置最先 指定下次婚配从末了一名最先,就婚配不到了
xReg.lastIndex = 11; // 11
xReg.test(str); // false

xReg.lastIndex; // 0
var indexReg = /^(?:http|https).+\/jwebui\/pages\/themes\/(\w+)\/\1\.jspx(\?\S+)?$/i ;

上面是一个F8中搜检是不是为首页的正则表达式。

  • 最最先的^ 和末了的$离别示意婚配的最先和完毕。

  • (?:http|https)示意二者之一,这么写黑白猎取的组婚配,()不会被分组存储。也能够写成(http|https) 然则背面的\1就须要替代成\2了,由于这么写时此处形成了第一个分组。

  • .+ 就是恣意字符最少涌现一次。

  • \/jwebui\/pages\/themes\/ 就是婚配字符串"/jwebui/pages/themes/"

  • (\w+) 作为第一个分组,示意恣意字母或数字或下划线或汉字最少涌现一次。

  • \1示意对第一个分组的援用,再反复第一分组的内容 。

  • \.jspx 示意.jspx

  • (\?\S+)? 示意(\?\S+) 婚配的内容涌现0次或一次。个中:

    • \? 示意

    • \S+ 示意恣意可见字符涌现最少一次。
      `

exec()

正则对象的exec要领,能够返回婚配效果。假如发明婚配,就返回一个数组,成员是每个婚配胜利的子字符串,不然返回null

假如正则示意式包含圆括号(即含有“组婚配”),则返回的数组会包含多个成员。第一个成员是悉数婚配胜利的效果,背面的成员就是圆括号对应的婚配胜利的组。也就是说,第二个成员对应第一个括号,第三个成员对应第二个括号,以此类推。悉数数组的length属性即是组婚配的数目再加1。

var ipReg = /(\d{1,3}\.){3}(\d{1,3})/;
var ipStr = 'My ip is "192.168.118.47" , please tell me yours';

ipReg.exec(ipStr); // ["192.168.118.47", "118.", "47"]

上面第一段代码示意一个简朴的IP磨练,数字的1-3位以后紧跟一个.,接着这个团体要涌现3次,末了再有一段数字的1-3位。效果数组中,第一个值示意婚配到的效果,以后的示意正则分组婚配到的内容。

假如正则表达式加上g修饰符,则能够运用屡次exec要领,下一次搜刮的位置从上一次婚配胜利完毕的位置最先。同时还能够指定lastIndex,使之下次从指定位置最先(可见之前的test示例)。

var ipLastReg = /\d+(?=;)/g;

var ipsStr = '192.168.118.47;192.168.118.46;192.168.118.48;';

ipLastReg.exec(ipsStr); // ["47"]
ipLastReg.exec(ipsStr); // ["46"]
ipLastReg.exec(ipsStr); // ["48"]

上面代码中正则中的(?=;)示意先行断言,示意只婚配在;前面\d+

假如只是为了获得是不是婚配,请运用 RegExp.test()要领或字符串实例的.search() 替代,效力更高。

字符串相干要领

之所以称之为字符串相干要领是由于其是在字符串上挪用的(虽然ES6最先,内部挪用的是正则上的要领,但照样在字符串上供应的进口)。

  • match():返回一个数组,成员是一切婚配的子字符串。

  • search():根据给定的正则表达式举行搜刮,返回一个整数,示意婚配最先的位置。

  • replace():根据给定的正则表达式举行替代,返回替代后的字符串。

  • split():根据给定划定规矩举行字符串支解,返回一个数组,包含支解后的各个成员。

match()

match要领对字符串举行正则婚配,返回婚配效果。此要领要领与正则对象的exec要领异常相似:婚配胜利返回一个数组,婚配失利返回null。假如正则表达式带有g修饰符,则该要领与正则对象的exec要领行动差别,会一次性返回一切婚配胜利的效果。

var ipLastReg = /\d+(?=;)/g;
var ipsStr = '192.168.118.47;192.168.118.46;192.168.118.48;';

ipsStr.match(ipLastReg); // ["47", "46", "48"]

上面的正则是婚配IP中的末了一名,个中运用了(?=;)意为先行断言,示意只婚配在;之前的内容,然则不包含;。关于更多先行断言,请看下文。

search()

search要领,返回第一个满足前提的婚配效果(可直接运用字符串,不一定是正则对象)在悉数字符串中的位置。假如没有任何婚配,则返回-1

var nowDateStr = '2016-11-1';
var testReg = /-/g;

nowDateStr.search(testReg); // 4
// 再次查找照样4
nowDateStr.search(testReg); // 4

//  搜检lastIndex 并设置 
testReg.lastIndex; // 0
testReg.lastIndex = 6;
nowDateStr.search(testReg); // 4  效果仍为4

search要领老是从字符串的最先位置查找,与正则表达式的g修饰符和lastIndex属性无关。

replace()

replace要领能够替代婚配的值,返回替代后的新字符串。它接收两个参数,第一个是搜刮情势(可直接运用字符串,不一定是正则对象),第二个是替代的内容(可运用字符串或一个函数)。搜刮情势假如不加g修饰符,就替代第一个婚配胜利的值,不然替代一切婚配胜利的值。

个中replace要领的第二个参数能够运用美圆标记$,用来指代所替代的内容,详细以下所示:

  • $& 指代婚配的子字符串。

  • $` 指代婚配效果前面的文本。

  • $' 指代婚配效果背面的文本。

  • $n 指代婚配胜利的第n组内容,n是从1最先的自然数。

  • $$ 指代美圆标记$。

var re = /-/g; 
var str = '2016-11-01';
var newstr = str.replace(re,'.');
console.log(newstr);  // "2016.11.01"

'hello world'.replace(/(\w+)\s(\w+)/, '$2 $1');
// "world hello"

'abc'.replace('b', '[$`-$&-$\']');
// "a[a-b-c]c"

第二个参数为函数:

function toCamelStyle(str) {
    // 婚配-以及以后的一个字符,个中这个字符在一个分组内
    var camelRegExp = /-([a-z])/ig;

    return str.replace(camelRegExp, function(all, letter) {
        // all为婚配到的内容,letter为组婚配        
        return letter.toUpperCase();
    });
}

toCamelStyle('margin-left'); // "marginLeft"
toCamelStyle('aa-bb-cccc'); // "aaBbCccc"

以上代码展现经由过程正则将aa-bb-cccc如许的字符串转化为aaBbCccc 这类情势。replace回调函数吸收两个参数,第一个为婚配到的内容,第二个为婚配到的分组,有若干组就能够传若干个参数,在此以后还能够有两个参数,一个为婚配到内容在原字符串的位置,另一个是原字符串。

split()

split要领根据正则划定规矩支解字符串,返回一个由支解后的各个部份构成的数组。该要领接收两个参数,第一个参数是分开划定规矩(可直接运用字符串,不一定是正则对象),第二个参数是返回数组的最大成员数。

'2016-11-01'.split('-'); // ["2016", "11", "01"]
'2016-11-01'.split(/-/); // ["2016", "11", "01"]

贪欲情势和懒散情势

当正则表达式中包含能接收反复的限定符时,一般的行动是(在使悉数表达式能获得婚配的前提下)婚配尽量多的字符,称之为贪欲情势

比方:

var s = 'aaa';
s.match(/a+/); // ["aaa"]

偶然,我们更须要懒散婚配,也就是婚配尽量少的字符。前面给出的限定符都能够被转化为懒散婚配情势,只需在它背面加上一个问号?。如许.*?就意味着婚配恣意数目的反复,然则在能使悉数婚配胜利的前提下运用起码的反复。

var s = 'aaa';
s.match(/a+?/); // ["a"]

以下是一些申明

  • *? 反复恣意次,但尽量少反复

  • +? 反复1次或更屡次,但尽量少反复

  • ?? 反复0次或1次,但尽量少反复

  • {n,m}? 反复n到m次,但尽量少反复

  • {n,}? 反复n次以上,但尽量少反复

也就是说默许状况下,都是贪欲情势,加上一个时就转化为了懒散情势,也称非贪欲情势。

组婚配

一般一个()中的内容就构成了一个分组,此分组内容将被存储,可在以后的正则表达式(运用\1-\9)和相干要领中(运用 $1-$9)援用,前面已引见过了,就不再说了。

关于组婚配,另有以下几种状况:

非捕捉组

(?:x) 称为非捕捉组(Non-capturing group),示意不返回该组婚配的内容,即婚配的效果中不计入这个括号。

// 一般婚配
var url = /(http|ftp):\/\/([^/\r\n]+)(\/[^\r\n]*)?/;

url.exec('http://google.com/');
// ["http://google.com/", "http", "google.com", "/"]

// 非捕捉组婚配
var url = /(?:http|ftp):\/\/([^/\r\n]+)(\/[^\r\n]*)?/;

url.exec('http://google.com/');
// ["http://google.com/", "google.com", "/"]

以后先行断言先行否认断言也都黑白捕捉组

先行断言

x(?=y)称为先行断言(Positive look-ahead),x只需在y前面才婚配,y不会被计入返回效果。

比方之前婚配ip的例子:

var ipLastReg = /\d+(?=;)/g;
var ipsStr = '192.168.118.47;192.168.118.46;192.168.118.48;';

ipsStr.match(ipLastReg); // ["47", "46", "48"]

上面正则对象中(?=;)就示意只婚配在;之前的内容,然则不包含;

先行否认断言

x(?!y)称为先行否认断言(Negative look-ahead),x只需不在y前面才婚配,y不会被计入返回效果。

var xreg = /\d+(?!%)/g ;
xreg.exec('100% is 1'); // ["10"]
xreg.exec('100% is 1'); // ["1"]
/\d+?(?!%)/.exec('100% is 1'); // ["1"]

上面代码示意婚配不在%前的数字,xreg中直接誊写的\d+ 示意贪欲情势,因而第一次婚配到的是10,第二次才会婚配到背面的1,由于作为数字10本身也不在%前面,正则不会将100当做一个团体(注重:这里须要定义一个正则对象来挪用,直接以字面量情势的正则挪用时,每次挪用都是一个新对象,效果始终是10)。

为了一次婚配到末了的1,我们在\d+以后加一个?将其转为非贪欲情势即可。

为了一次婚配到前面100中的1,我们在\d+以后加一个?将其转为非贪欲情势即可。

ES6之前,JavaScript中不支撑后行断言否认后行断言,ES6中添加了对此的支撑,请看以后的ES扩大部份。

ES6扩大

组织函数

RegExp组织函数的参数有两种状况。

  • 第一种状况是,参数是字符串,这时候第二个参数示意正则表达式的修饰符(flag)。

  • 第二种状况是,参数是一个正则示意式,此时不能有第二个参数,会返回一个原有正则表达式的拷贝。

ES6 针对第二种状况,许可传入第二个参数,用于设置第一个参数正则表达式的修饰符。

var regex = new RegExp(/xyz/, 'i'); // ES6之前 语法毛病

new RegExp(/abc/ig, 'i'); // ES6中效果为: /abc/i  

字符串的正则要领

字符串对象共有4个要领,能够运用正则表达式:match()replace()search()split()

ES6将这4个要领,在言语内部悉数挪用RegExp的实例要领,从而做到一切与正则相干的要领,全都定义在RegExp对象上。

修饰符

ES6对正则表达式添加了u修饰符,寄义为“Unicode情势”,用来准确处理大于uFFFF的Unicode字符。也就是说,会准确处理四个字节的UTF-16编码。

ES6还为正则表达式添加了y修饰符,叫做“粘连”(sticky)修饰符。

y修饰符的作用与g修饰符相似,也是全局婚配,后一次婚配都从上一次婚配胜利的下一个位置最先。差别之处在于,g修饰符只需盈余位置中存在婚配便可,而y修饰符确保婚配必需从盈余的第一个位置最先,这也就是“粘连”的涵义。

var s = 'aaa_aa_a';
var r1 = /a+/g;
var r2 = /a+/y;

// 第一次都能准确婚配
r1.exec(s); // ["aaa"]
r2.exec(s); // ["aaa"]

// 第二次效果就不一致了
r1.exec(s); // ["aa"]
r2.exec(s); // null

个人明白,\y是相似于在每次婚配时隐式地添加了^,示意最先位置。

属性

ES5中,正则对象存在source属性,用于返回正则表达式本身。

ES6中,又添加了flags属性,用于返回正则对象的一切修饰符。

后行断言

后行断言于先行断言相反。比方/(?<=y)x/ 示意婚配x,然则请求x必需在y背面。

同理 后行否认断言则为:/(?<!=y)x/ 示意婚配x,然则请求x不能在y背面。

须要注重的是,存在后行断言时,正则实行递次发生了转变,会先婚配后行断言的这部份,再婚配其他的的,递次变成了从右向左。因而一些婚配操纵的效果能够大不一致,而且正则中的\1-\9的援用递次也会发生变化。

参考链接

原文宣布在我的博客JavaScript正则表达式RegExp,迎接接见!

毛病修改

先行否认断言中

为了一次婚配到末了的1,我们在\d+以后加一个?将其转为非贪欲情势即可。

为了一次婚配到前面100中的1,我们在\d+以后加一个?将其转为非贪欲情势即可。

    原文作者:依韵_宵音
    原文地址: https://segmentfault.com/a/1190000008812676
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞