博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

记开发过程中偶遇的一个bug

Posted on 2012-07-10 14:53  _edifier_  阅读(387)  评论(1)    收藏  举报

几天前做评论显示,偶遇一个小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,'&amp;').replace(/"/g,'&quot;').replace(/\</g,'&lt;').replace(/\>/g,'&gt;').replace(/\'/g,'     &#39;').replace(/\u00A0/g,'&nbsp;').replace(/(\u0020|\u000B|\u2028|\u2029|\f)/g,'&#32;');
    }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也真的可以让我们成长不少。问题最终得到了解决,有兴趣的朋友可以自己去试着用正则的思路解决这个问题,在此我就不多做赘述了!