正则表达式-2

1.简单的转义字符— “\”反斜杠
正则中的特殊字符想匹配本身的含义都需要加转义字符

var str = "\\\\";
var pattern = /\\\\/;//反斜杠自身也需要转义
console.log(pattern.exec(str));//["\\"]

\n==\x0A(十六进制) 换行符
\t==\u0009(unicode编码常用语匹配汉字) 制表符
unicode编码中汉字的范围是[\u4e00-\u9fa5]

2.字符类
[abc123@] 匹配其中的任意一个字符,按顺序匹配,只要一个完成就整个匹配完成
[^js] 在[]中^表示取反,匹配除了js之外的字符
[a-z] 匹配小写英文字母,开始与结尾可以灵活选择,前面的要小于等于后面的字符
[\u4e00-\u9fa5] 匹配全部汉字
[a-zA-Z] 匹配大小写英文字母
[0-9] 匹配数字,最大只能为9
[a-zA-Z0-9@_]

3.常用字符类

/./ 匹配除\n之外的所有字符
/\./ 匹配"."
/\w/ 匹配[a-zA-Z0-9_]
/\W/ 匹配[^a-zA-Z0-9_]//正则中大写一般读表示小写的反面
/\d/ 匹配[0-9]
/\D/ 匹配[^0-9]
/\s/ 匹配空格和制表符
/\S/ 匹配除空格制表符之外的字符
/[\s\d]/ 匹配空格或数字

4.重复

{n} 确定重复匹配数目
var str = '110';
var pattern = /\d{3}/;//匹配次数为0时,无返回;不为0时,若无匹配值,返回null 
console.log(pattern.exec(str));//['110']
{n,m} 匹配n或m个,不能有空格
var str = '110';
var pattern = /\d{1,3}/;//前面小于等于后面
console.log(pattern.exec(str));//['110'],当str第一位为数字时,总是优先匹配大的重复数;若无匹配则返回null
var str = 's6930184,地址是北京西城区';
var pattern1 = /\d{0,1}/;//注意0的特殊情况!
alert(pattern1.exec(str));//当str第一位不为数字时,与0组合,默认不匹配,没有返回,null都没有!
{n,} 匹配至少n个
var str = '110';
var pattern = /\d{1,}/;//匹配至少一个
console.log(pattern.exec(str));//['110'],若字符串长度大于重复次数,则匹配整个字符串;若无匹配则返回null
? 匹配0个或1var str = '110';
var pattern = /\d?/;//匹配0个或1个
console.log(pattern.exec(str));//['1'],当str第一位为数字时,若有匹配项,则匹配一个
var str = 's6930184,地址是北京西城区';
var pattern1 = /\d?/;
alert(pattern1.exec(str));//当str第一位不为数字时,默认不匹配,没有返回,null都没有!
+ 至少匹配一次,等同于{1,}
var str = '110';
var pattern = /\d+/;//{1,}
console.log(pattern.exec(str));//['110']//若无匹配则返回null
* 匹配0次或更多
var str = '110';
var pattern = /\d*/;
console.log(pattern.exec(str));//['110'],当str第一位为数字时,若有匹配项,则全部返回
var str = 's6930184,地址是北京西城区';
var pattern1 = /\d*/;
alert(pattern1.exec(str));//当str第一位不为数字时,默认不匹配,没有返回,null都没有!

5.非贪婪重复
正则在默认情况下都是贪婪的,只要条件允许就会尽量多的匹配;在量词后加?可以转换为非贪婪匹配(条件允许情况下尽可能少匹配)

/a{1,}?/只匹配一次
/a{2,3}?/匹配两次
/a??/匹配0/a+?/匹配一次
/a*?/匹配0
var str = "aaab";
var pattern = /a+b/;
console.log(pattern.exec(str));//["aaab"]
var pattern1 = /a+?b/;
console.log(pattern1.exec(str));//仍然是["aaab"]

正则从左边开始寻找第一个可能匹配的,而不是最合适的,所以从第一个a就开始匹配(尽可能少并不是只能匹配一个)

var str = "<td><p>a<p></td><td><p>a<p></td>";
var pattern = /<td>.*<\/td>/;
console.log(pattern.exec(str));//贪婪匹配
var pattern = /<td>.*?<\/td>/;//量词后面
console.log(pattern.exec(str));//非贪婪匹配,只匹配第一个td

6.选择、分组和引用
1)选择 |

/html|css|js/ //三选一,只要有一个匹配到了就停止
var str = 'ab';
var pattern = /a|ab/;
console.log(pattern.exec(str));//['a']

上例从字符串左边第一个字符串开始,依次从正则最左边开始尝试匹配,若找到就停止继续匹配

2)分组
量词只能影响它前面的一个字符

var str = 'abab';
var pattern = /ab+/;
console.log(pattern.exec(str));//['ab'],+只能影响b
var pattern = /(ab)+/;
console.log(pattern.exec(str));//['abab'],用小括号分组
var str = 'abcd';
var pattern = /(ab)c/;//捕获性的分组
console.log(pattern.exec(str));//['abc','ab'],返回的数组中第一项为总体匹配的,第二项为第一个分组匹配的,第三项为第二个分组匹配的
var pattern = /(?:ab)c/;//?:代表非捕获分组
console.log(pattern.exec(str));//['abc']

嵌套的分组从左开始,根据左括号的顺序判断分组顺序

var str = 'abcd';
var pattern = /(a(b(c)))/;
console.log(patern.exec(str));//['abc','abc','bc','c']

正则中直接使用分组(捕获性)

var str = 'ab cd ab';
var pattern = /(ab) cd \1/;//\1代表第一个分组,\2代表第二个
console.log(pattern.exec(str));//['ab cd ab','ab'];
var str = '<p><a>这是一段文字</a></p>';
var pattern = /<([a-zA-Z]+)>(.*?)<\/\1>/;
console.log(pattern.exec(str));

<([a-zA-Z]+)>中[a-zA-Z]是为了匹配大写或小写的字母,+是因为标签不一定只有一个字母组成,()是为了通过\1引用以保证前后匹配项一致
(.*?)分组的目的是为了获取外标签内的值,非贪婪只获取第一个匹配项
.exec()方法返回的数组,若没有分组就只有一项,若有分组则根据分组顺序添加分组的匹配值;有index和input属性,index表示匹配项在原数组中的下标,input表示用于匹配的原数组

pattern.exec(str).index/input

7.指定匹配位置
1)首尾匹配–经常用于表单验证
^用于[ ]中表示取反,若直接写则表示以…开头
$用于正则表示以…结尾

var str = 'js html';
var pattern = /^js/;//首匹配
var str = 'html js';
var pattern = /js$/;//尾匹配
    var str = "s1191293921234";
    var pattern = /^\d+$/;
    console.log(pattern.exec(str));

当设置首尾匹配时,只有全是数字才能匹配上

利用首尾匹配对getElementsByClassName进行浏览器兼容:

	function getByClassName(className, parentNode) {//传入类名及父节点
		if (document.getElementsByClassName) {//如果支持则采用原方式
			return document.getElementsByClassName(className);
		} else {
			parentNode = parentNode || document;//如果用户没有传入父节点,则采用默认值
			var nodeList = [];
			var allNodes = parentNode.getElementsByTagName('*');
			var pattern = new RegExp('(^|\\s+)' + className + '($|\\s+)');
			//由于使用变量,所以只能通过构造函数创建;节点可以拥有多个类名,指定的类名可能在开头、结尾(一端为空格)或中间(两端都为空格)
			//'(^|\\s+)'表示指定类名位于开头或左方为空格(可以有多个,所以用+),字符串中\也需要转义,所以写成\\s;
			//'($|\\s+)'表示指定类名位于结尾或右方为空格(同样可以有多个),()是为了不影响变量而人为划分的分组。
			for (var i = 0; i < allNodes.length; i++) {
				if (pattern.test(allNodes[i].className)) {//如果通过正则验证则推入数组
					nodeList.push(allNodes[i]);
				}
			}

			return nodeList;//返回指定类名的节点列表
		}
	}

2)单词边界匹配
\b 表示匹配单词的边界,也即是\w和\W的边界,并不会返回值

    var str = "@@@123_asd@@@";
    var pattern = /\b.*\b/;
    alert(pattern.exec(str));//123_abc

利用单词边界匹配对getElementsByClassName进行浏览器兼容:

var pattern = new RegExp('\\b' + className + '\\b');

单词边界可以忽略指定类名的位置,只要它是一个单词就可以!

前瞻性匹配 --只会匹配括号之前的内容!

/aaa(?=bbb)/  //只有aaa后跟的是bbb才匹配它,匹配的仍然只是aaa!

负向前瞻性匹配

/aaa(?!bbb)/  //如果aaa后跟的是bbb就不匹配它

8.RegExp对象
构造函数需要对转义字符进行双重转义

new RegExp('\\\\') //双重转义,实际只匹配一个\

1)RegExp的实例方法:test exec
exec方法不管执行多少遍,它只会从第一个位置开始执行。
如果加上g修饰符进行全局匹配,它依然只会返回一个值,但每执行一次,都从当前匹配项向后搜寻(index记录的值会发生变化)。
pattern.lastIndex属性在非全局情况下都是0,一旦设置全局,它的值会发生变化,会记录匹配上值的下一个位置;当再次执行exec时,先读取lastIndex的值再向后匹配;如果搜寻到字符串末尾也未匹配上,会将lastIndex重置为0,下一次执行又从头开始搜寻。

var str = '1.js 2.js 3.js';
var pattern = /js/g;
var total = 0,match = '',result;

while((result = pattern.exec(str)) != null){//运行到末尾才会为null,可以通过循环获取每一个匹配值
	total++;
	match += total + ':' + result[0] + ':' + result.index + '\n';
}
match += '共找到' + total + '处匹配\n';
console.log(match);

test方法在全局匹配时lastIndex变化规律与exec一致,非全局匹配时lastIndex不工作。

toString() toLocaleString() valueOf()方法都返回正则的字面量形式,都继承自Object对象。

2)RegExp实例属性

var str = 'js js js';
var pattern = /js/ig;
pattern.ignoreCase //判断是否忽略大小写
pattern.global //判断是否全局
pattern.multiline //判断是否多行
pattern.source //返回字面量形式对应的字符串
pattern.lastIndex //当前匹配项的下一个位置,默认为0

3)构造函数的属性
不常用,不同浏览器实现效果不一样
Js中只有合法的标识符才能用“.”来表示,所有能用点表示的都能够用[ ]来表示,但[ ]中能传入其它字符,不一定能转换为点

var str = 'js js js';
var pattern = /(j)s/;
pattern.exec(str);
RegExp.input //待匹配的字符串
RegExp.$_ //上一个的别名
RegExp.lastMatch //最近一次匹配的字符串
RegExp[$&] //别名
RegExp.leftContext //最近一次匹配的字符串左边的内容,别名['$`']
RegExp.rightContext //最近一次匹配的字符串右边的内容,别名['$'']
RegExp.lastParen //最近一次分组匹配的字符串,别名['$+']
RegExp.$1~$9 //表示分组匹配的内容,最多9个

9.String对象中与正则相关的方法
1)search

var str = 'html js';
pattern = /js/;
console.log(str.search(pattern));//匹配上返回位置,未找到返回-1,与全局无关系
console.log(str.search('js'));//传入字符串,通过构造函数将其转化为正则再匹配

2)match

var str = 'js js js';
pattern = /js/;
console.log(str.match(pattern));//非全局匹配时返回值与exec方法一样;有分组时仍然与exec一样
pattern = /(j)s/g;
console.log(str.match(pattern));//全局匹配时,返回所有匹配值组成的数组,但会忽略分组的匹配值---['js','js','js']

与exec的对比:
match只有在非全局的情况下才会返回分组中匹配到的内容,全局匹配只返回所有匹配到的字符,忽略分组;
exec无论是否全局匹配都会返回分组中匹配到的内容,都只会返回当前匹配到的一个内容,而不是全部返回。

var str = '1.js\n2.js\n3.js';
var pattern = /js/m;//多行匹配
console.log(str.match(pattern));//非全局时只会返回一个
var pattern = /js/mg;//多行与全局一起
console.log(str.match(pattern));//返回所有匹配值,但仅有g时结果一样的,m体现不出作用
pattern = /js$/mg;//m需要与全局和首尾匹配搭配才能体现作用

3)split

var str = 'html,css,js';
var pattern = /,/;
console.log(str.split(pattern));//如果传入',',实际也是通过构造函数转换为正则再匹配

4)replace
传入字符串时,该方法只替换一个

var str = 'I love js js';
var pattern = /js/g;
console.log(str.replace(pattern,'html'));//使用正则时设置全局匹配才能全部替换

repalce方法返回替换后的新字符串

var str = 'I love js';
var pattern = /(js)/;
document.write(str.replace(pattern,'<strong style="color:red;">$1</strong>'));

当正则中设置分组时,可在replace中通过$1~9引用

var str = 'someone is anyone';
var pattern = /some|any/g;//敏感词替换
console.log(str.replace(pattern,function($0){
	var result = '';
	for(var i = 0;i < $0.length;i++){
		result += '*';//匹配项有几个字符就替换为几个星号
	}
	return result;
}));

replace方法如果第二个参数是函数的话,那么函数的第一个参数代表的是正则匹配出来的内容,第二个参数表示分组()中的内容,但要注意它并不只是第一个分组内容,而是分组匹配到的所有内容!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值