精华 ES2015系列(三) 正则表达式
发布于 8 年前 作者 zhangmingkai4315 3989 次浏览 来自 分享

本节内容我们继续探讨关于ES2015的一些新的内容,在js中我们经常用一些正则表达式去匹配验证一些表单信息,比如email,url,password格式等等。在ES6版本中,引入了一些新的正则表达式的用法,通过这些方法,允许我们实现一些更灵活的的正则验证, 本节内容的实例代码来源于<You don’t know JS> 系列书籍。

Unicode 标志位

ES6通过引入了一个新的“u”标志位,允许对于Unicode字符串进行匹配,在原来的ES5版本中,正则表达式对于扩展字符集比如中文汉字,认为这是两个字符,所以如果想要匹配到这些扩展集合,必须同时对两个字符进行匹配。引入的“u”标志位,则告诉正则表达式,使用UTF-16的方式去解释字符,这时候对于一个汉字来说,就可以当做是一个字符来处理了。

我们通过一个简单的例子,来看一下js对于字符的处理:

	/𝄞/.test( "𝄞-clef" );
	true
	
	/^.-clef/.test( "𝄞-clef" );
	false
	
	/^.-clef/u.test( "𝄞-clef" );
	// true

上述的例子中,“.”代表了除了回车和换行之外的所有字符,如果其中的𝄞是一个字符的话,第二个表达式应该是返回真才对,但实际上他是占据了两个字符,所以无法匹配上,表达式返回假值。当我们设置了u标志位的时候,他就被认为是一个字符处理了,所以最终第三个的表达式为真。

Sticky 粘滞位

ES6中增加的另一个标志位为y,代表了开启一个粘滞模式匹配。通过该方式我们可以设置匹配的精确位置,代码如下:

	var a=/hello/
	a.lastIndex  			     // 0
	a.test("say: hello world")  // true
	a.lastIndex  				 // 0
	var b=/hello/y
	
	b.test("say: hello world")   // false
	b.lastIndex=5
	b.test("say: hello world")   // true
	b.lastIndex                  // 10
	b.test("say: hello world")   // false
	b.lastIndex                  //0

比如我们只想匹配某个字符串从第10个字符开始位置是否是我们需要的字符串,就可以通过手动的指定lastIndex来移动匹配锚。 可见y参数对于那些可被预测匹配位置的,或者固定格式字符串匹配比较高效。

另外一个例子中使用了稍微复杂的正则匹配,先来看下正则表达式:

	/\d+\.\s(.*?)(?:\s|$)/

正则表达式如下图所示:

image

这个表达式中我们\d+代表至少一个数字,.代表匹配一个.符号,\s代表空白符,(.*)代表了匹配任意的字符串,后面跟的?代表了非贪婪捕获,这样我们就会将剩余的字符全部匹配上,(?:)代表了匹配但不捕获,用于返回的结果中不去包含该分组,\s|$ 代表空白或者结束符号

对于非粘滞位的操作如下:

	var str = "1. foo 2. bar 3. baz";
	var re = /\d+\.\s(.*?)(?:\s|$)/
	
	str.match( re );
	// ["1. foo ", "foo"]
	str.match( re );
	// ["1. foo ", "foo"]
	str.match( re );
	// ["1. foo ", "foo"]

不管我们匹配多少次结果都是一样的,因为并未移动匹配位置。当我们使用y粘滞位的时候,则结果如下面代码中所示:

	var re = /\d+\.\s(.*?)(?:\s|$)/y
	str = "1. foo 2. bar 3. baz";

	str.match( re );
	// ["1. foo ", "foo"]
	str.match( re );
	// ["2. bar ", "bar"]
	str.match( re );
	// ["3. baz", "baz"]
	

当然使用全局/g 也可以实现依次的输入输出,但是可控的匹配位置操作还是增加了很多使用上的灵活性,可以满足一些特殊的匹配需求。

使用注意

在javascript中使用正则表达式的地方很多,比如test(),match(),String.search(),String.split()等等,不同的函数在使用/g与/y时候的行为有所不同,有些函数会在使用/y的时候依照lastIndex位置开始匹配,而有一些则忽略该位置定义,比如search()不管设置lastIndex与否,使用\y时候都从开始位置匹配。具体的可参考链接。使用时多留意。

1 回复
回到顶部