天天看点

给属性添加双引号

给HTML标签中的属性添加双引号。

<a href=xxx>改为:<a href="xxx">

LeXRus的第一个正则如下:

/(?!\<\w+)(\s+\w+)\=([^>\"\s]+)/ig       

第一个括号没看明白,JS应该是不支持。所以我擅自给删掉了,剩下的正则如下:

/(\s+\w+)\=([^>\"\s]+)/ig       

第一个括号里的\s+\w+匹配的是属性名。

然后是=,不用转义。

第二个括号里的[^>\"\s]+匹配属性值。不匹配>”和空格。这里的引号不用转义。在意思不改变的情况下,稍微改了改,正则如下:

/(\s+\w+)=([^>"\s]+)/ig       

需要注意的是这个正则不匹配=两边有空格的属性,例如href = xxx。相匹配的话就改成:

/(\s+\w+)\s*=\s*([^>"\s]+)/ig       

代码:

str=str.replace(/(?!\<\w+)(\s+\w+)\=([^>\"\s]+)/ig,'$1="$2"');       

其中’$1=”$2”’就实现了给属性值添加上双引号。不过ncs指出了这个正则替换的几个问题,一是上面的空格问题,二是如果非标签内部有等号,且前面又恰巧有空白字符的话,它将会被误识别为属性,例如:

<a href=xxx target=yyy title = asdfasf> test=sd

里面的test=sd也会被匹配。三是如果属性原来使用了单引号,会被再包上一层双引号……

来看看LeXRus前辈的新正则替换方法:

str=str.replace(/(?!<\w+)(\s+\w+)\s*=\s*([^>\"\s]+)(?=[^>]*>)/ig,'$1="$2"')
.replace(/\"\'([^\'\"]+)\'\"/ig,'\"$1\"');       

先来看第一个正则:

/ (\s+\w+)\s*=\s*([^>"\s]+)(?=[^>]*>)/ig       

结尾新添的(?=[^>]*>)意在解决普通文本中有等号被误识别为属性的问题:

就没问题了,但是

<a href=xxx target=yyy title = asdfasf> test=sd<tag>又一个标签</tag>

中的test=sd<tag>又会被识别为属性。

我觉得改成下面的正则就没问题了:

/(\s+\w+)\s*=\s*([^<>"\s]+)(?=[^<>]*>)/ig       

分别在第二个括号的字符集合和最后的反向预查的字符集合中添加了一个<。

下面再来分析第二个正则,

/\"\'([^\'\"]+)\'\"/ig       

这个正则用于匹配双引号,单引号多层嵌套的情况,同样,不用转义,修改正则如下:

/"'([^'"]*)'"/ig

这样基本任务就完成了。测试代码如下:

<script type="text/javascript"> 
 function rp(str,trg){ 
  var reg1 = /(\s+\w+)\s*=\s*([^<>"\s]+)(?=[^<>]*>)/ig 
  var reg2 = /"'([^'"]*)'"/ig; 
  str=str.replace(reg1,'$1="$2"').replace(reg2,'\"$1\"'); 
  trg.value=str; 
 } 
 </script> 
 <textarea id="sou" style="width:100%"> 
 <a href = xxx name=aaa target=_blank title='asdfasf'
  asfd=asfd 
 </textarea> 
 <input type="button" onclick="rp(sou.value,sou)" value="replace"/>       
hint=i am lexrus 
这样的属性会有问题,不过我感觉不加引号的话,属性值里就不可能有空格,否则会被识别为多个属性了。不过看到最后ncs的回帖我就哭了: onclick=if(document.forms.length>0) 这样的属性怎么办?大于号会被识别为标签结束……还是分离行为与文档吧。补充一下,其实修补一下正则也可以解决,只要改成如下正则即可:        
/(\s+\w+)\s*=\s*([^"\s]+)(?=[^<>]*>)/ig       
就是去掉第二个括号内字符集合里的<>。最后这个问题也解决。

继续阅读