RegExp 正则

前言

正则表达式作为javascript的一个利器,在程序开发中,关键时候起了大作用,省时,还省了不少代码量。js的又一大利器,jquery。其源码中,不少地方都用到了正则。

RegExp基础

简单类

RegExp是一个构造函数,通过它可以构造正则实列对象,RegExp(pattern),依据这个pattern (模式或者正则规则) 来匹配文本,然后将匹配到的结果放入Array. 方便操作。同样也可以通过字面量的形式定义正则。

通过实列来看看:

var str = 'shanshan is very beatful!!!'		
//需求,将beatful匹配出来
var reg = /\bbeatful\b/	//字面量
var regExp = new RegExp('beatful', 'g')	//构造

上面输出结果为:数组index: 0,就是匹配的大串

在这里插入图片描述

范围类

[ ],指代一个字符,内部表示范围。比如[0-9],匹配0-9范围内的数字。但是每次仅仅匹配一个结果,如果需要多个数字匹配,前面需要加量词 + 。
正则,匹配 16进制数。 /[a-fA-F0-9]+/g

str = '5A20z';
str.match( /[a-fA-F0-9]+/);
console.log(str.match( /[a-fA-F0-9]+/))

输出结果,
在这里插入图片描述

负向类

负向类也是范围的一种,用于匹配字符集合中反义补充字符集,[^a-zA-Z0-9],匹配非拉丁字母表中字母数字字符。等价于 ,\W. 其中 - 表示字符范围。

量词

故名思意,量词就是计数用的。那么在正则中,量词是怎样的一个应用场景呢!看实列,

var str = '4571;a497466;dfgh569879';
 console.log(str2.match(/[0-9][0-9]/g),'ok');
两次,匹配单位出现次数  {n}
console.log(str2.match(/[0-9]{2}/g));   
{m,n} 至少m次,至多n次
 console.log(str2.match(/[0-9]{3,4}/g));
{m,} 至少m次
 console.log(str2.match(/[0-9]{3,}/g));
 ? 零次或着1次 , =》{0,1}
 console.log(str2.match(/[0-9]?/g))
 console.log(str2.match(/[0-9]{0,1}/g));
 * 0 次或者多余 0 次 =》 {0, }
 + 1次或者多余1次, {1,}

运行结果,
在这里插入图片描述
在这里插入图片描述
说明:上面图,箭头标识处,第一处,是为了标识每一次匹配所用到的量词,而打印的标记;第二处才是匹配的内容。
接下来分析与正则匹配相关的函数

?,+ ,匹配单位出现最小次数也满足规则,为什么实际匹配中却按最大的返回呢?这是贪婪量词的作用,每次匹配,它会将所有匹配字符纳入,并按最大返回。

贪婪

这里的贪婪,同人性贪婪一样同意,不过这里要说的是贪婪的量词,量词很贪婪。
属于贪婪范畴的量词有,? ,*, +。它们均会安匹配字串最大length返回。

惰性

惰性量词,是由 +?,*?两个构成,他们会找到匹配的字串最小length返回。

通配符 预定义类

字符

. = [^\n\r] 除回车和换行都可以匹配
\d = [0-9]
\D = [^0-9]
\w = [a-zA-Z0-9_] 数字字母下划线
’ 列: 一个变量命名状态: /[a-zA-Z_]\w*/
\W = [^a-zA-Z_0-9] 非数字字母下划线,%, =
\s = [\t\n\x0B\f\r ] 空格或者空格
例如 /\s\w*/ 匹配 “foo bar” 中的 ’ bar’
\S = [^\t\n\x0B\f\r ] 非空格或者空格,
例如,/\S\w*/ 匹配 “foo bar” 中的 ‘foo’。

边界(不占长度)

\b 表示边界(两个字符的中间位置) 一边是\w,另一边是\W
\B 不是边界
^ 表示开始,尖括号在中括号外边
$ 表示结束

分组

一个正则表达式,可以对整个串匹配,同样可以依照()中的pattern进行匹配

在这里插入图片描述
test

var str = 'mom and dad';
console.log(str.match( /mom( and dad )?/g ) ); 
console.log(str.match( /mom( and dad )?/ ) );  //不加g 此时分组也会匹配到

输出结果
在这里插入图片描述
从输出结果可以看出,添加了参数g,数组中添加分组索引,在没有添加全局参数g 的情况,忽略分组索引,index.

反向引用

\n : n 是一个正整数。一个反向引用(back reference),指向正则表达式中第 n 个括号(从左开始数)中匹配的子字符串。
应用格式

方式一.(pattern)匹配pattern,同时捕获结果,自动设定组号
\1,RegExp.$1:反向引用,(对前面的匹配结果的复制引用)
方式二.(?<name组名>pattern)匹配pattern,同时捕获结果,设定name为组 号
\k,对前面匹配结果的复制引用

test

str5 = 'python javascript javascript go go';
console.log(str5.match(/(\b[a-zA-Z]+\b)\s+\1/));   //\1捕获前面的分组,并进行继续向下匹配捕获
console.log(str5.match(/(?<n1>\b[a-zA-Z]+\b)\s+\k<n1>/))

输出结果

在这里插入图片描述

零宽先行/后行断言

零宽,通常是括号里的匹配项()不占据长度
先行断言:”先行断言“指的是,x只有在y前面才匹配,必须写成/x(?=y)/。
后行断言:“后行断言”正好与“先行断言”相反,x只有在y后面才匹配,必须写成/(?<=y)x/。

实列总结:

//零宽(不占字符长度)先行\后行断言
str5 = ‘reaaa;rcaaa=bbb=;’;
//寻找两字符,字符后面以分号结尾
console.log(str5.match(/.{2}(?=;)/g)); //零宽先行断言
//寻找4个字符,且以ea开头
console.log(str5.match(/(?<=ea).{4}/g)); //零宽后行断言,注意以什么开头断言时,需要加 <,在匹配字符后面不需要加
//寻找三个字母,其后不已分号结尾
console.log(str5.match(/[a-z]{3}(?!;)/g)); //零宽负向(不是,或者反的)后行断言
//寻找不已re开头的三个字母
console.log(str5.match(/(?<!re)a{3}/)); //index:8, aaa

或 |

逻辑运算符或,用来连接两个或者多个正则表达式
test
模拟此法分析器,对变量函数声明,进行匹配。

var regExp1 = /^var\s+[a-zA-Z]\w*;/g;  //变量申明正则
var regExp2 =  /^function\s+[a-zA-Z]\w*\s*(\)\{\}/g //函数申明正则
//合并
var regExp3 = /^var\s+[a-zA-Z]\w*;|^function\s+[a-zA-Z]\w*\s*\(\)\{\}/g

var str_v = 'var aaa;';  //变量申明
var str_f = 'function f(){}';    //函数申明字符串

console.log( str_v.match( /^var\s+[a-zA-Z]\w*;|^function\s+[a-zA-Z]\w*\s*\(\)\{\}/g ));	//success
console.log( str_f.match( /^var\s+[a-zA-Z]\w*;|^function\s+[a-zA-Z]\w*\s*\(\)\{\}/g ));	//success

接下来楼一下与正则相关的函数。如下介绍的函数,都是经常用到的。由于内容篇幅有限,不宜一一列举。

String类func

search()

search(regExp), 匹配直接量和对象,返回整数,返回第一个匹配的位置;匹配不到返回 -1;

var str = 'hello shanshan haha shanshan javascript';
console.log(str5.search(/\bshanshan\b/));   //4
console.log(str5.search(/\bshanshan\b/g));   //4,注意,忽略全局匹配 g

match()

match(regExp) 直接量和对象

  • 有g情况,返回所有匹配的最大串。
  • 无g ,数组中的元素,index:表示第一个匹配的最大串的开始位置,其他表示分组;input:表示原始的串。

列:匹配电话号码
思路:大陆电话号码是11位
1.以数字1开头
2.第二位是[3578]范围
3.第三位[0-9]任意
4.有些时候号码3.4,7.8位之间还得有 -
代码实现

var regExp = /^1[3578][0-9-?\d{4}-?\d{4}]$/	//匹配 pattern
//match()
var str5 = '15815647894';
console.log(str5.match(/^1[34578][0-9]-?\d{4}-?\d{4}$/g))
str5 = '11111111111';   //null
console.log(str5.match(/^1[34578][0-9]-?\d{4}-?\d{4}$/g))
str5 = '130-1234-4567';
console.log(str5.match(/^1[34578][0-9]-?\d{4}-?\d{4}$/g))

输出结果,
在这里插入图片描述

replace()

replace(regExp/substr,replacement);
参数详情,

  • regExp直接量或对象,substr 需要替换的子串
  • replacement 替换的串,或函数。
// str5 = 'python is powerful python';
//把python替换成大写
// console.log(str5.replace(/\bpython\b/g,'PYTHON'));  //加 g 匹配并替换全部,否则只替换匹配的第一个
// console.log(str5.replace('python','PYTHON'))	//替换第一个

replacement还有几个特殊值: 在这里插入图片描述 test

str5 = 'aaa-bbb   ccc-ddd';
替换子串位置
console.log(str5.replace(/([a-z]+)-([a-z]+)/g,'$2-$1'))	  //bbb-aaa   ddd-ccc

这里补充一下,replacement,还可以是一个回调函数,函数返回值作为替换子串. 如果第一个参数是正则表达式,并且其为全局匹配模式,那么这个方法将被多次调用,每次匹配都会被调用。
该回调函数参数详情
在这里插入图片描述
test

function replacer(match, p1, p2, p3, offset, string) {
  // p1 is nondigits, p2 digits, and p3 non-alphanumerics
  return [p1, p2, p3].join(' - ');
}
// 在匹配的字串后面加 -
var newString = 'abc12345#$*%'.replace(/([^\d]*)(\d*)([^\w]*)/, replacer);
console.log(newString);  // abc - 12345 - #$*%

split()

split(separator,howmany),切断字符串

  • separator 正则,字符串
  • limit 限制数组长度
    注意:
    如果在str中省略或不出现分隔符,则返回的数组包含一个由整个字符串组成的元素。如果分隔符为空字符串,则将str原字符串中每个字符的数组形式返回。

test

var str = 'hello is ver good good good good study day day up'
 console.log( str.split( /\s+/ ) );
 console.log( str.split( /\s+/,4 ) );   
 console.log( str.split ( '' " ) );    //不添加长度切出整个字符

在这里插入图片描述

RegExp_func

test()

regExp test(string) boolean 测试str是否匹配 pattern
test

var str = 'hello is ver good good good good study day day up';

console.log( /\bhello\b/.test( str ) );    //true
console.log( /\bhelloa\b/.test( str ) );   //false

exce()

regExp exce(string) 返回数组(找不到返回null)

  • 没有 g ,返回结果跟match返回结果一样。
  • 有 g, lastIndex中放入字串(匹配的字串)结束位置的下一位,每次调用往后移。
    lastMatch 非标准属性是正则表达式的静态和只读属性,含有最后匹配到的字符串,通过RegExp类调用

    RegExp.prototype.lastIndex
    下次匹配开始的字符串索引位置。

var regExp = /\bgood\b/g;
regExp.lastIndex = 17; //设定第一个匹配字串字符索引,可以继续向下匹配,直到匹配索引为-1;
// console.log(regExp.exec(str5));
// console.log(regExp.lastIndex); //lastIndex

应用 Date_function format()

需求:给定 xxxx年MM月dd日,正则匹配替换成相应的字串
var d1 = new Date();
Date.prototype.format = function (fmt){
var obj = {
‘M+’: this.getMonth() + 1,
‘d+’: this.getDate(),
‘h+’: this.getHours(),
‘m+’: this.getMinutes(),
‘s’: this.getSeconds()
};
if(/y+/.test(fmt)){
var year = this.getFullYear().toString();
if(RegExp.lastMatch.length <= year.length){
year = year.substr(-RegExp.lastMatch.length); //截取year的后几位
}
fmt = fmt.replace(RegExp.lastMatch, year);
console.log(RegExp.lastMatch);
}
for(var k in obj){
var r = new RegExp(k) //new RegExp(/’(’+ k +’)’/)
if(r.test(fmt)){
var x = obj[k].toString();
if(RegExp.lastMatch.length > x.length){
//补零
x = ‘0000’ + x;
x = x.substr(-RegExp.lastMatch.length);
console.log(RegExp.lastMatch,1);
}
fmt = fmt.replace(RegExp.lastMatch, x);
}
}
return fmt;
};

console.log(d1.format(‘yyyy年MM月dd日hh时mm分’));

特点是:如果指定字母,y,m,M…超过常规日期个数,截取对应的日期,输出合理的日期。月日,.时分秒位数<1,会补零。

才疏学浅,不足之处,敬请指正。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值