天天看點

給屬性添加雙引号

給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       
就是去掉第二個括号内字元集合裡的<>。最後這個問題也解決。

繼續閱讀