第一种:
我们常做的一件事情,就是在文章系统中,截取一定长度的文章标题,超过指定长度,就加“...”
如两个字符串: string str1 = "中国人要啊abc呀~"; string str2 = "1中国人23456abc呀~";
要截取后,输出:
str1 = "中国人要..."; str2 = "1中国人2...";
即要把中英文混合的字符串,在截取后,长度要一致,即8个字节的长度(不包括三个点),而且不能出现中文被从中间截断的情况。于是写了个方法:
1 using System.Text.RegularExpressions; 2 3 // 4 public static string getStr(string s,int l) 5 { 6 string temp = s ; 7 if (Regex.Replace(temp,"[\u4e00-\u9fa5]","zz",RegexOptions.IgnoreCase).Length<=l) 8 { 9 return temp; 10 } 11 for (int i=temp.Length;i>=0;i--) 12 { 13 temp = temp.Substring(0,i); 14 if (Regex.Replace(temp,"[\u4e00-\u9fa5]","zz",RegexOptions.IgnoreCase).Length<=l-3) 15 { 16 return temp + ""; 17 } 18 } 19 return ""; 20 }
调用:
string content ="中国人啊abc呀呀呀呀";
content = getStr(content,13);
第二种:
很早以前写过一篇文章(用C#截取指定长度的中英文混合字符串),但是对性能没有测试,有人说我写的这个方法性能有问题,后来想,可能真会有BT之需求要求传入一个几万K甚至几M体积的字符串进来,那将会影响正则Match的速度,比如文章系统中就极有可能用到,今天有点时间,就改进了一下,代码如下:
public static string getStr(string s,int l,string endStr) { string temp = s.Substring(0, (s.Length < l)?s.Length:l); if (Regex.Replace(temp,"[\u4e00-\u9fa5]","zz",RegexOptions.IgnoreCase).Length<=l) { return temp; } for (int i=temp.Length;i>=0;i--) { temp = temp.Substring(0,i); if (Regex.Replace(temp,"[\u4e00-\u9fa5]","zz",RegexOptions.IgnoreCase).Length<=l-endStr.Length) { return temp + endStr; } } return endStr; }
此修改版的方法多加了个参数"string endStr",是指当字符串"string s"超过指定长度"int l"时,对结尾的处理,比如要不要加上省略号"..."或加上其它字符。 另外,添加了省略号之后,省略号长度也是算在结果的长度之内了。
用法如:
getStr("中国1中国中国中1111中国", 23,"") //output:中国1中国中国中1111中国 getStr("中国1中国中国中1111中国", 23,"...") //output:中国1中国中国中1111...
getStr("中国1中国中国中1111中国中国", 23,"") //output:中国1中国中国中1111中国
getStr("中国1中国中国中1111中国中国", 23,"...") //output:中国1中国中国中1111...
第三种:
----------------------------------------------------------------------
补充:"kpz"回复说上边的方法会截取失真,而我又无法做到穷尽测试,所以换了另一种写法,为了考虑性能结果把逻辑搞的有点"晕",反复测试了多次,代码如下:
1 public static string getStr2(string s, int l,string endStr) 2 { 3 string temp = s.Substring(0, (s.Length < l+1)?s.Length:l+1); 4 byte[] encodedBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(temp); 5 6 string outputStr = ""; 7 int count = 0; 8 9 for (int i = 0; i < temp.Length; i++) 10 { 11 if ((int)encodedBytes[i] == 63) 12 count += 2; 13 else 14 count += 1; 15 16 if (count <= l-endStr.Length) 17 outputStr += temp.Substring(i,1); 18 else if (count>l) 19 break; 20 } 21 22 if (count<=l) 23 { 24 outputStr=temp; 25 endStr=""; 26 } 27 28 outputStr += endStr; 29 30 return outputStr; 31 }
用法和参数含义均同前,注意省略号也占位置,算了长度。