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>
为什么呢?看不懂代码,求javascript高手指点一下。
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>
为什么呢?看不懂代码,求javascript高手指点一下。
10 回答11.7k 阅读
2 回答3.2k 阅读✓ 已解决
4 回答2.2k 阅读✓ 已解决
3 回答1.2k 阅读✓ 已解决
3 回答843 阅读✓ 已解决
3 回答1k 阅读✓ 已解决
2 回答1.2k 阅读✓ 已解决
(这段正则表达式怎么那么像jQuery源码中的呢?)
这个正则表达式的目的是将自闭合形式的标签修改成起始标签相应出现的形式。
即把"<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
表示匹配全局匹配,有多个匹配到的,就有多个被替换,如//i
表示忽略大小写匹配,如(略)一般形式1:
/<.*\/>/
,这个就是匹配<div .../>
这种标签形式的字符串look-ahead
部分:(?!area|br|col|embed|hr|img|input|link|meta|param)
这部分表示说右边不能这些
area
,br
等情况,jQuery的中觉得像<input />
这种形式不需要修改。如:
捕获分组:
(([w:]+)[^>]*)
这里开始引入捕获分组概念,捕获分组和非捕获分组是有区别的(也没有必要细说)。
捕获分组有意义的地方在于可以被引用,如
$1
和$2
这里就是引用了捕获分组1和捕获分组2的意思。(([w:]+)[^>]*)
这里有两对括号,从左边往右,每对组成一个捕获分组,所以一共两个捕获分组,捕获分组1是整体(([w:]+)[^>]*)
,捕获分组2是([w:]+)
。捕获分组2的要匹配的是
w
和(或):
的多次出现的情况,+
是量词表示匹配的次数,至少出现一次,如引用捕获分组,相当于引用实际被匹配到的字符串,如题意
捕获分组1匹配到内容是
div xxx=yyy
,捕获分组2匹配到内容是div
,所以
replace
方法的第二参数中刚好使用到他们,将他们分别填入$1
和$2
。然后:
[^>]*
这部分也很关键,在前面捕获分组2匹配到那个标签tag
后,这部分把后续完整的字符保留下来,当然像下面的情况就没有起到匹配替换的效果。正则表达式量词有
?
,+
,*
。一般形式2:
.*