几天前做评论显示,偶遇一个小bug,感觉颇有趣味故记录于此!
大家知道一般评论内容分两段:前面是评论的话题,后面是评论的内容。而话题一般是以链接的形式出现,所以,对评论内容要做如下处理:
function replaceLink(str){ var reg = /#(.+)#/gi; return str.replace(reg,function(){ return '<a href="###">' + arguments[0] + '</a>'; }); }
而全部评论内容要当做html文本被浏览器解析,我们又不确定使用者会输入什么,所以,我们需要下面这个方法来对全部评论内容进行一次转码:
function encodeHTML(str){ if(typeof str == 'string'){ return str.replace(/\&/g,'&').replace(/"/g,'"').replace(/\</g,'<').replace(/\>/g,'>').replace(/\'/g,' '').replace(/\u00A0/g,' ').replace(/(\u0020|\u000B|\u2028|\u2029|\f)/g,' '); }else{ return false; } }
这时候,问题就来了,我们是在a标签替换之前对评论内容做encodeHTML,还是在之后做呢!?如果在之后做,那a标签也会被干掉,很明显不行!如果放在之前做,那replaceLink方法里面的正则reg就不满足需求了,因为单引号和双引号的转码值含有#号,匹配会出错!诚然,一个合理的正则可以解决这个问题,但在这里,我想给大家看的是另外一种方法(重写replaceLink):
function replaceLink(str){ var matchArr = str.match(/#([^#]*)#/ig); for(var i=0,len=matchArr.length;i<len;i++){ var reg = new RegExp(matchArr[i], 'gi'); str = str.replace(reg, '_'); } str = encodeHTML(str); for(var i=0,len=matchArr.length;i<len;i++){ var link = '<a href="###">' + encodeHTML(matchArr[i]) + '</a>'; str = str.replace(/_/, link); } return str; }
看到这里估计有人会扔砖说这什么啊,明明改一行代码搞定的问题非要弄成这样。在此我想表达的是:任何问题都有很多种解决思路,精妙的算法可以使代码看起来小巧、美观,但有时复杂的代码,往往更能把解决问题的思路表现出来!
改bug的过程真的是一个从焦头烂额到豁然开朗的过程,一个好的bug也真的可以让我们成长不少。问题最终得到了解决,有兴趣的朋友可以自己去试着用正则的思路解决这个问题,在此我就不多做赘述了!
浙公网安备 33010602011771号