Skip to content

【jQuery源码】rxhtmlTag

money edited this page Jul 27, 2018 · 1 revision

var rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi;

var value="<div/>";

value = value.replace( rxhtmlTag, "<$1></$2>" );

console.log(value);

这段代码的输出结果为:

<div></div>

这个正则表达式的目的是将自闭合形式的标签修改成起始标签相应出现的形式。

即把"<div/>"修改成"<div></div>"

"<div data-name='xxx'/>"修改成"<div data-name='xxx'></div>"的形式。

下面详细说明正则表达式含义。

/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([w:]+)[^>]*)/>/gi

1.整体可以看成//gi的形式

2.再剥开一层看到的是/<.*\/>/的形式

3.再仔细看到2中描述.*,更准确一点是(?!area|br|col|embed|hr|img|input|link|meta|param)(([w:]+)[^>]*)两部分

4.3中的左部分表示环视look-ahead向前看,但是具有否定意义

5.3中的右部分表示要匹配的内容,它是((.*).*)的一般形式

6.一般形式的正则表示,如.*

修饰符:

//g表示匹配全局匹配,有多个匹配到的,就有多个被替换,如

value = "<div/><div/>"

value.replace( rxhtmlTag, "<></>" );

//结果:"<div></div><div></div>"

//i表示忽略大小写匹配,如(略)

一般形式1:/<.*\/>/,这个就是匹配<div .../>这种标签形式的字符串

look-ahead部分:(?!area|br|col|embed|hr|img|input|link|meta|param)

这部分表示说右边不能这些area,br等情况,jQuery的中觉得像<input />这种形式不需要修改。

如:

value = "<input type='text' />"

value.replace( rxhtmlTag, "<></>" );

//结果:<input type='text' />

捕获分组:(([w:]+)[^>]*)

这里开始引入捕获分组概念,捕获分组和非捕获分组是有区别的(也没有必要细说)。

捕获分组有意义的地方在于可以被引用,如$1和$2这里就是引用了捕获分组1和捕获分组2的意思。

(([w:]+)[^>]*)这里有两对括号,从左边往右,每对组成一个捕获分组,所以一共两个捕获分组,捕获分组1是整体(([w:]+)[^>]*),捕获分组2是([w:]+)

捕获分组2的要匹配的是w和(或):的多次出现的情况,+是量词表示匹配的次数,至少出现一次,如

re = /<[\w:]+\/>/

re.test("<i/>"); //true

re.test("</>"); false

引用捕获分组,相当于引用实际被匹配到的字符串,如题意

value = "<div xxx=yyy/>"

value = value.replace( rxhtmlTag, "<></>" );

//结果:"<div xxx=yyy></div>"

捕获分组1匹配到内容是div xxx=yyy,捕获分组2匹配到内容是div

所以replace方法的第二参数中刚好使用到他们,将他们分别填入$1和$2。

然后:[^>]*这部分也很关键,在前面捕获分组2匹配到那个标签tag后,这部分把后续完整的字符保留下来,当然像下面的情况就没有起到匹配替换的效果。

value = "<div xxxx=yyyy>/>"

value = value.replace( rxhtmlTag, "<></>" );

//结果:<div xxxx=yyyy>/>

正则表达式量词有?,+,*。

一般形式2:.*

Clone this wiki locally