js中根据字数截取字符串,不能截断url

  今天收到个需求:

  1,给一个文字,对输出的文字进行截取,保留400个字符

  2,截取内容最后如果是url,保留完整url地址

  3,添加省略号......

  ----

  其中对url的保留比较麻烦,尤其是有两个相同url时不能采用indexOf获取其字符位置。

  处理结果:

  

js中根据字数截取字符串,不能截断url

相关代码:

  

复制代码 代码如下:

  String.prototype.sizeAt = function(){

  var nLen = 0;

  for(var i = 0, end = this.length; i<end; i++){

  nLen += this.charCodeAt(i)>128?2:1;

  }

  return nLen;

  };

  String.prototype.cutStr = function(n, sCut){

  if(this.sizeAt() <= n){

  return this;

  }

  sCut = sCut || "";

  var max = n-sCut.sizeAt();

  var nLen = 0;

  var s = this;

  for(var i =0,end = this.length;i<end;i++){

  nLen += this.charCodeAt(i)>128?2:1;

  if(nLen>max){

  s = this.slice(0,i);

  s += sCut;

  break;

  }

  }

  return s.toString();

  };

  String.prototype.cutStrButUrl = function(n, sCut){

  if(this.sizeAt() <=n){

  return this.toString();

  }

  sCut = sCut || "";

  var max = n-sCut.sizeAt();

  var s = this;

  //查找所有包含的url

  var aUrl = s.match(/https?:\/\/[a-zA-Z0-9]+(\.[a-zA-Z0-9]+)+([-_A-Z0-9a-z\$\.\+\!\*\/,:;@&=\?\~\#\%]*)*/gi);

  //当第max个字符刚好在url之间时,bCut会被设置为flase;

  var bCut = true;

  if(aUrl){

  //对每个url进行判断

  for(var i=0, endI = aUrl.length;i<endI;i++){

  var sUrl = aUrl[i];

  //可能出现两个相同url的情况

  var aP = s.split(sUrl);

  var nCurr = 0;

  var nLenURL = sUrl.sizeAt();

  var sResult = "";

  for(j = 0, endJ = aP.length; j<endJ; j++){

  nCurr +=aP[j].sizeAt();

  sResult +=aP[j];

  sResult += sUrl;

  //当前字数相加少于max但添加url超过max:即会截到url

  if(nCurr < max && nCurr + nLenURL>max){

  s = sResult + sCut;

  bCut = false;

  break;

  }

  nCurr += nLenURL;

  }

  if(bCut === false){

  break;

  }

  };

  }

  if(bCut){

  s = s.cutStr(n, sCut);

  }

  return s.toString();

  };

  console.log('正常截取20个字符'.cutStrButUrl(20,'......'));

  console.log('正常截取20个字符,但我超了'.cutStrButUrl(20,'......'));

  console.log('有url的字符串http://www.baidu.com你能截取到吗?'.cutStrButUrl(20,'......'));

  console.log('http://www.baidu.com有两个相同url的字符串http://www.baidu.com好吗?'.cutStrButUrl(51, '......'));