在一个项目中,要用到手机发送短信,但是使用的短信猫却无法支持大于70个字符的情况,而且经常收到有朋友的短信,比较长的手机都会自动将它切成几个短信发送。有时候很搞,收到的短信有两条,第二条就只有一个句号而已。或者几乎这种手机都不会去理解语义,直接就在70个字符处切割。
要做到完全理解语义也不大可能,但是突然想到,为什么不可以根据分隔符去切割呢?至少这样子不会把一段完整的内容不会被强行分割出来。
比如有下面一段话:
如果短信的长度超过70个字符,程序就会自动根据短信中的分隔符进行分割,在不是非常苛刻的情况下,它不会将一个词分成两段来发,比如,不会出现"你好"的前一个字在第一条短信内,而"好"字在第二条短信内!这都是在不增加短信数量的情况下优化的!
普通的短信会分成:
1. 如果短信的长度超过70个字符,程序就会自动根据短信中的分隔符进行分割,在不是非常苛刻的情况下,它不会将一个词分成两段来发,比如,不会出现"你(70个字符)
2.好"的前一个字在第一条短信内,而"好"字在第二条短信内!这都是在不增加短信数量的情况下优化的!(47个字符)
使用下面的程序,可以得到以下的另一种分法:
1.如果短信的长度超过70个字符,程序就会自动根据短信中的分隔符进行分割,在不是非常苛刻的情况下,它不会将一个词分成两段来发,比如,(待续)==>68
2.(续)不会出现"你好"的前一个字在第一条短信内,而"好"字在第二条短信内!这都是在不增加短信数量的情况下优化的!==>56
很显然,第二种情况才是比较人性化一点的。看看程序吧:
private const String PRE_STR = "(续)"; private const String SUF_STR = "(待续)"; private static int PRE_STR_LEN = PRE_STR.Length; private static int SUF_STR_LEN = SUF_STR.Length; private static int EXT_LENGTH = PRE_STR_LEN + SUF_STR_LEN; private static int MAX_LEN = 70; //每个短信最长大小 /// <summary> /// 切割字符串,使每串不超过70个字符 /// </summary> /// <param name="str"></param> /// <returns></returns> private List<String> StringSplit(String str) { List<String> msms = new List<string>(); bool star = true; while (true) { if (!star) { str = PRE_STR + str; } int lenght = str.Length; int msgCoun = getMsgCount(lenght); int nullSpace = getLastMsgLeftCount(lenght, msgCoun); if (str.Length <= MAX_LEN) { //不用分割 msms.Add(str); break; } else { int splitIndex = getSplitIndex(str, nullSpace); string tempStr = str.Substring(0, splitIndex); msms.Add(tempStr + String SUF_STR); str = str.Substring(splitIndex); } star = false; } return msms; } /// <summary> /// 获取一条短信最小可以分多少条短信 /// </summary> /// <param name="t">短信长度</param> /// <returns></returns> private int getMsgCount(int t) { if (t < MAX_LEN) return 1; int n = (int)((t + MAX_LEN - 2 * EXT_LENGTH - 1) / (MAX_LEN - EXT_LENGTH)); return n; } /// <summary> /// 计算最后一条信息还可添加多少个字符 /// </summary> /// <param name="t">短信总字符数</param> /// <param name="n">短信理想情况分页数</param> /// <returns></returns> private int getLastMsgLeftCount(int t,int n) { if (t <= MAX_LEN) return MAX_LEN - t; int l = MAX_LEN + (MAX_LEN - EXT_LENGTH) * (n - 1) - t; return l; } private static char[] splitChar = new char[] { ',',' ','.',';','!',')','>','}',']',',',' ','。',';','!',')','》','/n','/t'}; /// <summary> /// 比较智能地去判断分割的位置,尽量在有分隔符的地方分割 /// </summary> /// <param name="str">str的长度一定大于MAX_LEN</param> /// <param name="space">剩余可用空间大小</param> /// <returns></returns> private int getSplitIndex(String str,int space) { if (space > 0) { for (int i = MAX_LEN - SUF_STR_LEN - 1, d = (MAX_LEN - SUF_STR_LEN - space - 1); i >= d; --i) { foreach (char c in splitChar) { if (str[i] == c) { //匹配 Console.WriteLine(i + 1); return i + 1; } } } } return MAX_LEN - SUF_STR_LEN; } public static void Main(String[] args) { string str = "如果短信的长度超过70个字符,程序就会自动根据短信中的分隔符进行分割,在不是非常苛刻的情况下,它不会将一个词分成两段来发,比如,不会出现/"你好/"的前一个字在第一条短信内,而/"好/"字在第二条短信内!这都是在不增加短信数量的情况下优化的!"; List<String> ms = new MobileRegistService().StringSplit(str); foreach (String m in ms) { Console.WriteLine(m + "==>" + m.Length); } }
转自:http://www.cnblogs.com/ycoe/archive/2008/12/25/1362596.html