字符串操作助手类

  1 using System;
  2 using System.Collections;
  3 using System.Text;
  4 using System.Text.RegularExpressions;
  5 
  6 namespace Commons.Helpers
  7 {
  8     /// <summary>
  9     /// 字符串操作助手类
 10     /// </summary>
 11     public class StringHelper
 12     {
 13         #region 获取处理好的行数据
 14         public static SortedList GetSortedList(string line)
 15         {
 16             string src = line.Replace("\"\"", "'");
 17 
 18             MatchCollection col = Regex.Matches(src, ",\"([^\"]+)\",", RegexOptions.ExplicitCapture);
 19 
 20             SortedList sl = new SortedList();
 21             IEnumerator ie = col.GetEnumerator();
 22             while (ie.MoveNext())
 23             {
 24                 string patn = ie.Current.ToString();
 25                 int key = src.Substring(0, src.IndexOf(patn)).Split(',').Length;
 26                 if (!sl.ContainsKey(key))
 27                 {
 28                     sl.Add(key, patn.Trim(new[] { ',', '"' }).Replace("'", "\""));
 29                     src = src.Replace(patn, ",,");
 30                 }
 31             }
 32 
 33             string[] arr = src.Split(',');
 34             for (int i = 0; i < arr.Length; i++)
 35             {
 36                 if (!sl.ContainsKey(i))
 37                 {
 38                     sl.Add(i, arr[i]);
 39                 }
 40             }
 41 
 42             return sl;
 43         }
 44         #endregion
 45 
 46         #region 字符串左补零
 47         /// <summary>
 48         /// 字符串左补零
 49         /// </summary>
 50         /// <param name="inStr">原字符串</param>
 51         /// <param name="len">补零后字符串的总长</param>
 52         /// <returns></returns>
 53         public static string StringPadLeftZero(string inStr, int len)
 54         {
 55             string outStr = inStr;
 56 
 57             if (inStr.Length < len)
 58             {
 59                 outStr = inStr.PadLeft(len, '0');
 60             }
 61 
 62             return outStr;
 63         }
 64         #endregion
 65 
 66         #region 转换中文的逗号并去掉最后的逗号
 67         /// <summary>
 68         /// 转换中文的逗号并去掉最后的逗号
 69         /// </summary>
 70         /// <param name="strList">逗号串起来的字符串</param>
 71         /// <returns>最后没用逗号的字符串</returns>
 72         public static string DeleteLastComma(string strList)
 73         {
 74             //判断是否为空
 75             if (!String.IsNullOrEmpty(strList))
 76             {
 77                 //转换中文的逗号
 78                 strList = Regex.Replace(strList, "", ",");
 79                 //判断最后一位是否逗号
 80                 while (strList.IndexOf(',') == 0 || strList.LastIndexOf(',') == strList.Length - 1)
 81                 {
 82                     strList = strList.IndexOf(',') == 0 ? strList.Substring(1) : strList;
 83                     strList = strList.LastIndexOf(',') == strList.Length - 1 ? strList.Substring(0, strList.Length - 1) : strList;
 84                 }
 85             }
 86             return strList;
 87         }
 88         #endregion
 89 
 90         #region 过滤特殊符号
 91         /// <summary>
 92         /// 过滤特殊符号
 93         /// </summary>
 94         /// <param name="text">字符串</param>
 95         /// <returns>返回特殊符号</returns>
 96         public static string FilerSymbol(string text)
 97         {
 98             StringBuilder sb = new StringBuilder();
 99             string symbol = "@,#,$,*,_,&,^,|,\\,/";
100             string[] symbolGroup = symbol.Split(',');
101 
102             foreach (string t in symbolGroup)
103             {
104                 int exist = text.IndexOf(t);
105 
106                 //判断是否存在特殊符号
107                 if (exist != -1)
108                 {
109                     sb.Append(t);
110                     sb.Append(",");
111                 }
112             }
113             string result = DeleteLastComma(sb.ToString());
114 
115             return result;
116         }
117         #endregion
118 
119         #region 自定义的替换字符串函数
120         /// <summary>
121         /// 自定义的替换字符串函数
122         /// </summary>
123         public static string ReplaceSymbol(string text)
124         {
125             string symbol = "@,#,$,*,~,&,^,|,\\,/,%,(,),+,{,},:,;,.,<,>,?,\",',!,[,],`,€";
126             string[] symbolGroup = symbol.Split(',');
127 
128             foreach (string t in symbolGroup)
129             {
130                 text = text.Replace(t, "_");
131             }
132 
133             return text.Replace(" ", "").Replace(",", "");
134         }
135         #endregion
136 
137         #region 合并字符
138         /// <summary>
139         /// 合并字符
140         /// </summary>
141         /// <param name="source">要合并的源字符串</param>
142         /// <param name="target">要被合并到的目的字符串</param>
143         /// <returns>合并到的目的字符串</returns>
144         public static string MergeString(string source, string target)
145         {
146             return MergeString(source, target, ",");
147         }
148 
149         /// <summary>
150         /// 合并字符
151         /// </summary>
152         /// <param name="source">要合并的源字符串</param>
153         /// <param name="target">要被合并到的目的字符串</param>
154         /// <param name="mergechar">合并符</param>
155         /// <returns>并到字符串</returns>
156         public static string MergeString(string source, string target, string mergechar)
157         {
158             if (String.IsNullOrEmpty(target))
159             {
160                 target = source;
161             }
162             else
163             {
164                 target += mergechar + source;
165             }
166             return target;
167         }
168         #endregion
169 
170         #region 删除最后一个字符
171         /// <summary>
172         /// 删除最后一个字符
173         /// </summary>
174         /// <param name="str">字符串</param>
175         /// <returns></returns>
176         public static string ClearLastChar(string str)
177         {
178             if (str == "")
179             {
180                 return "";
181             }
182 
183             return str.Substring(0, str.Length - 1);
184         }
185         #endregion
186 
187         #region 替换回车换行符为html换行符
188         /// <summary>
189         /// 替换回车换行符为html换行符
190         /// </summary>
191         /// <param name="str">字符串</param>
192         /// <returns></returns>
193         public static string StrFormat(string str)
194         {
195             string str2;
196 
197             if (str == null)
198             {
199                 str2 = "";
200             }
201             else
202             {
203                 str = str.Replace("\r\n", "<br />");
204                 str = str.Replace("\n", "<br />");
205                 str2 = str;
206             }
207             return str2;
208         }
209         #endregion
210 
211         #region 删除字符串尾部的回车/换行/空格
212         /// <summary>
213         /// 删除字符串尾部的回车/换行/空格
214         /// </summary>
215         /// <param name="str">字符串</param>
216         /// <returns></returns>
217         public static string RTrim(string str)
218         {
219             for (int i = str.Length; i >= 0; i--)
220             {
221                 if (str[i].Equals(" ") || str[i].Equals("\r") || str[i].Equals("\n"))
222                 {
223                     return str.Remove(i, 1);
224                 }
225             }
226             return str;
227         }
228         #endregion
229 
230         #region 生成指定数量的html空格符号
231         /// <summary>
232         /// 生成指定数量的html空格符号
233         /// </summary>
234         /// <param name="spacesCount">空格数量</param>
235         /// <returns></returns>
236         public static string GetSpacesString(int spacesCount)
237         {
238             StringBuilder sb = new StringBuilder();
239             for (int i = 0; i < spacesCount; i++)
240             {
241                 sb.Append("   ");
242             }
243             return sb.ToString();
244         }
245         #endregion
246 
247         #region 从字符串的指定位置截取指定长度的子字符串
248         /// <summary>
249         /// 从字符串的指定位置截取指定长度的子字符串
250         /// </summary>
251         /// <param name="str">原字符串</param>
252         /// <param name="startIndex">子字符串的起始位置</param>
253         /// <param name="length">子字符串的长度</param>
254         /// <returns>子字符串</returns>
255         public static string CutString(string str, int startIndex, int length)
256         {
257             if (startIndex >= 0)
258             {
259                 if (length < 0)
260                 {
261                     length = length * -1;
262                     if (startIndex - length < 0)
263                     {
264                         length = startIndex;
265                         startIndex = 0;
266                     }
267                     else
268                     {
269                         startIndex = startIndex - length;
270                     }
271                 }
272 
273                 if (startIndex > str.Length)
274                 {
275                     return "";
276                 }
277             }
278             else
279             {
280                 if (length < 0)
281                 {
282                     return "";
283                 }
284 
285                 if (length + startIndex > 0)
286                 {
287                     length = length + startIndex;
288                     startIndex = 0;
289                 }
290                 else
291                 {
292                     return "";
293                 }
294             }
295 
296             if (str.Length - startIndex < length)
297             {
298                 length = str.Length - startIndex;
299             }
300 
301             return str.Substring(startIndex, length);
302         }
303         #endregion
304 
305         #region 从字符串的指定位置开始截取到字符串结尾的了符串
306         /// <summary>
307         /// 从字符串的指定位置开始截取到字符串结尾的了符串
308         /// </summary>
309         /// <param name="str">原字符串</param>
310         /// <param name="startIndex">子字符串的起始位置</param>
311         /// <returns>子字符串</returns>
312         public static string CutString(string str, int startIndex)
313         {
314             return CutString(str, startIndex, str.Length);
315         }
316         #endregion
317 
318         #region 返回字符串真实长度, 1个汉字长度为2
319         /// <summary>
320         /// 返回字符串真实长度, 1个汉字长度为2
321         /// </summary>
322         /// <param name="str">字符串</param>
323         /// <returns>字符长度</returns>
324         public static int GetStringLength(string str)
325         {
326             return Encoding.Default.GetBytes(str).Length;
327         }
328         #endregion
329 
330         #region 字符串如果操过指定长度则将超出的部分用指定字符串代替
331         /// <summary>
332         /// 字符串如果操过指定长度则将超出的部分用指定字符串代替
333         /// </summary>
334         /// <param name="p_SrcString">要检查的字符串</param>
335         /// <param name="p_Length">指定长度</param>
336         /// <param name="p_TailString">用于替换的字符串</param>
337         /// <returns>截取后的字符串</returns>
338         public static string GetSubString(string p_SrcString, int p_Length, string p_TailString)
339         {
340             return GetSubString(p_SrcString, 0, p_Length, p_TailString);
341         }
342         #endregion
343 
344         #region 取指定长度的字符串
345         /// <summary>
346         /// 取指定长度的字符串
347         /// </summary>
348         /// <param name="p_SrcString">要检查的字符串</param>
349         /// <param name="p_StartIndex">起始位置</param>
350         /// <param name="p_Length">指定长度</param>
351         /// <param name="p_TailString">用于替换的字符串</param>
352         /// <returns>截取后的字符串</returns>
353         public static string GetSubString(string p_SrcString, int p_StartIndex, int p_Length, string p_TailString)
354         {
355             string myResult = p_SrcString;
356 
357             Byte[] bComments = Encoding.UTF8.GetBytes(p_SrcString);
358             foreach (char c in Encoding.UTF8.GetChars(bComments))
359             {
360                 //当是日文或韩文时(注:中文的范围:\u4e00 - \u9fa5, 日文在\u0800 - \u4e00, 韩文为\xAC00-\xD7A3)
361                 if ((c > '\u0800' && c < '\u4e00') || (c > '\xAC00' && c < '\xD7A3'))
362                 {
363                     //if (System.Text.RegularExpressions.Regex.IsMatch(p_SrcString, "[\u0800-\u4e00]+") || System.Text.RegularExpressions.Regex.IsMatch(p_SrcString, "[\xAC00-\xD7A3]+"))
364                     //当截取的起始位置超出字段串长度时
365                     if (p_StartIndex >= p_SrcString.Length)
366                     {
367                         return "";
368                     }
369 
370                     return p_SrcString.Substring(p_StartIndex,
371                                                  ((p_Length + p_StartIndex) > p_SrcString.Length) ? (p_SrcString.Length - p_StartIndex) : p_Length);
372                 }
373             }
374 
375             if (p_Length >= 0)
376             {
377                 byte[] bsSrcString = Encoding.Default.GetBytes(p_SrcString);
378 
379                 //当字符串长度大于起始位置
380                 if (bsSrcString.Length > p_StartIndex)
381                 {
382                     int p_EndIndex = bsSrcString.Length;
383 
384                     //当要截取的长度在字符串的有效长度范围内
385                     if (bsSrcString.Length > (p_StartIndex + p_Length))
386                     {
387                         p_EndIndex = p_Length + p_StartIndex;
388                     }
389                     else
390                     {   //当不在有效范围内时,只取到字符串的结尾
391 
392                         p_Length = bsSrcString.Length - p_StartIndex;
393                         p_TailString = "";
394                     }
395 
396                     int nRealLength = p_Length;
397                     int[] anResultFlag = new int[p_Length];
398 
399                     int nFlag = 0;
400                     for (int i = p_StartIndex; i < p_EndIndex; i++)
401                     {
402                         if (bsSrcString[i] > 127)
403                         {
404                             nFlag++;
405                             if (nFlag == 3)
406                             {
407                                 nFlag = 1;
408                             }
409                         }
410                         else
411                         {
412                             nFlag = 0;
413                         }
414 
415                         anResultFlag[i] = nFlag;
416                     }
417 
418                     if ((bsSrcString[p_EndIndex - 1] > 127) && (anResultFlag[p_Length - 1] == 1))
419                     {
420                         nRealLength = p_Length + 1;
421                     }
422 
423                     byte[] bsResult = new byte[nRealLength];
424 
425                     Array.Copy(bsSrcString, p_StartIndex, bsResult, 0, nRealLength);
426 
427                     myResult = Encoding.Default.GetString(bsResult);
428 
429                     myResult = myResult + p_TailString;
430                 }
431             }
432 
433             return myResult;
434         }
435         #endregion
436 
437         #region 取指定长度的字符串 中文字符计算加2
438         public static string GetUnicodeSubString(string str, int len, string p_TailString)
439         {
440             string result = String.Empty;// 最终返回的结果
441             int byteLen = Encoding.Default.GetByteCount(str);// 单字节字符长度
442             int charLen = str.Length;// 把字符平等对待时的字符串长度
443             int byteCount = 0;// 记录读取进度
444             int pos = 0;// 记录截取位置
445             if (byteLen > len)
446             {
447                 for (int i = 0; i < charLen; i++)
448                 {
449                     if (Convert.ToInt32(str.ToCharArray()[i]) > 255)// 按中文字符计算加2
450                         byteCount += 2;
451                     else// 按英文字符计算加1
452                         byteCount += 1;
453                     if (byteCount > len)// 超出时只记下上一个有效位置
454                     {
455                         pos = i;
456                         break;
457                     }
458 
459                     if (byteCount == len)// 记下当前位置
460                     {
461                         pos = i + 1;
462                         break;
463                     }
464                 }
465 
466                 if (pos >= 0)
467                 {
468                     result = str.Substring(0, pos) + p_TailString;
469                 }
470             }
471             else
472             {
473                 result = str;
474             }
475 
476             return result;
477         }
478         #endregion
479 
480         #region 自定义的替换字符串函数
481         /// <summary>
482         /// 自定义的替换字符串函数
483         /// </summary>
484         public static string ReplaceString(string SourceString, string SearchString, string ReplaceString, bool IsCaseInsensetive)
485         {
486             return Regex.Replace(SourceString, Regex.Escape(SearchString), ReplaceString, IsCaseInsensetive ? RegexOptions.IgnoreCase : RegexOptions.None);
487         }
488         #endregion
489 
490         #region 过滤危险脚本
491         public static string WipeScript(string html)
492         {
493             Regex regex1 = new Regex(@"<script[\s\s]+</script *>", RegexOptions.IgnoreCase);
494             Regex regex2 = new Regex(@" href *= *[\s\s]*script *:", RegexOptions.IgnoreCase);
495             Regex regex3 = new Regex(@" on[\s\s]*=", RegexOptions.IgnoreCase);
496             Regex regex4 = new Regex(@"<iframe[\s\s]+</iframe *>", RegexOptions.IgnoreCase);
497             Regex regex5 = new Regex(@"<frameset[\s\s]+</frameset *>", RegexOptions.IgnoreCase);
498             html = regex1.Replace(html, "");        //过滤<script></script>标记 
499             html = regex2.Replace(html, "");        //过滤href=javascript: (<a>) 属性 
500             html = regex3.Replace(html, " _disibledevent=");    //过滤其它控件的on...事件 
501             html = regex4.Replace(html, "");        //过滤iframe 
502             html = regex5.Replace(html, "");        //过滤frameset 
503             return html;
504         }
505         #endregion
506 
507         #region 分割字符串
508         /// <summary>
509         /// 分割字符串
510         /// </summary>
511         /// <param name="strContent">被分割的字符串</param>
512         /// <param name="strSplit">分隔符</param>
513         /// <returns></returns>
514         public static string[] SplitString(string strContent, string strSplit)
515         {
516             if (!String.IsNullOrEmpty(strContent))
517             {
518                 if (strContent.IndexOf(strSplit) < 0)
519                 {
520                     string[] tmp = { strContent };
521                     return tmp;
522                 }
523                 return Regex.Split(strContent, Regex.Escape(strSplit), RegexOptions.IgnoreCase);
524             }
525 
526             return new string[] { };
527         }
528 
529         /// <summary>
530         /// 分割字符串
531         /// </summary>
532         /// <param name="strContent">被分割的字符串</param>
533         /// <param name="strSplit">分隔符</param>
534         /// <param name="count">数组的数量</param>
535         /// <returns></returns>
536         public static string[] SplitString(string strContent, string strSplit, int count)
537         {
538             string[] result = new string[count];
539 
540             string[] splited = SplitString(strContent, strSplit);
541 
542             for (int i = 0; i < count; i++)
543             {
544                 result[i] = i < splited.Length ? splited[i] : String.Empty;
545             }
546 
547             return result;
548         }
549 
550         /// <summary>
551         /// 分割字符串
552         /// </summary>
553         /// <param name="strContent">被分割的字符串</param>
554         /// <param name="strSplit">分割符</param>
555         /// <param name="ignoreRepeatItem">忽略重复项</param>
556         /// <param name="maxElementLength">单个元素最大长度</param>
557         /// <returns></returns>
558         public static string[] SplitString(string strContent, string strSplit, bool ignoreRepeatItem, int maxElementLength)
559         {
560             string[] result = SplitString(strContent, strSplit);
561 
562             return ignoreRepeatItem ? ArrayHelper.DistinctStringArray(result, maxElementLength) : result;
563         }
564 
565         public static string[] SplitString(string strContent, string strSplit, bool ignoreRepeatItem, int minElementLength, int maxElementLength)
566         {
567             string[] result = SplitString(strContent, strSplit);
568 
569             if (ignoreRepeatItem)
570             {
571                 result = ArrayHelper.DistinctStringArray(result);
572             }
573             return ArrayHelper.PadStringArray(result, minElementLength, maxElementLength);
574         }
575 
576         /// <summary>
577         /// 分割字符串
578         /// </summary>
579         /// <param name="strContent">被分割的字符串</param>
580         /// <param name="strSplit">分割符</param>
581         /// <param name="ignoreRepeatItem">忽略重复项</param>
582         /// <returns></returns>
583         public static string[] SplitString(string strContent, string strSplit, bool ignoreRepeatItem)
584         {
585             return SplitString(strContent, strSplit, ignoreRepeatItem, 0);
586         }
587         #endregion
588 
589         #region 字符串重复
590         /// <summary>
591         /// 字符串重复N倍
592         /// </summary>
593         /// <param name="str"></param>
594         /// <param name="n"></param>
595         /// <returns></returns>
596         public static string RepeatString(string str, int n)
597         {
598             char[] arr = str.ToCharArray();
599             char[] arrDest = new char[arr.Length * n];
600             for (int i = 0; i < n; i++)
601             {
602                 Buffer.BlockCopy(arr, 0, arrDest, i * arr.Length * 2, arr.Length * 2);
603             }
604 
605             return new string(arrDest);
606         }
607         #endregion
608 
609         #region Base64解码
610         /// <summary>
611         /// Base64解码
612         /// </summary>
613         /// <param name="str"></param>
614         /// <returns></returns>
615         public static string Base64_Decode(string str)
616         {
617             byte[] bytes = Convert.FromBase64String(str);
618             return Encoding.UTF8.GetString(bytes);
619         }
620         #endregion
621 
622         #region Base64编码
623         /// <summary>
624         /// Base64编码
625         /// </summary>
626         /// <param name="str"></param>
627         /// <returns></returns>
628         public static string Base64_Encode(string str)
629         {
630             return Convert.ToBase64String(Encoding.UTF8.GetBytes(str));
631         }
632         #endregion
633 
634         #region 清理无效XML字符
635         /// <summary>
636         /// 清理无效XML字符
637         /// </summary>
638         /// <param name="input"></param>
639         /// <returns></returns>
640         public static string CleanInvalidCharsForXML(string input)
641         {
642             if (String.IsNullOrEmpty(input))
643             {
644                 return input;
645             }
646             StringBuilder builder = new StringBuilder();
647             char[] chArray = input.ToCharArray();
648             foreach (char t in chArray)
649             {
650                 int num2 = Convert.ToInt32(t);
651                 if ((((num2 < 0) || (num2 > 8)) && ((num2 < 11) || (num2 > 12))) && ((num2 < 14) || (num2 > 0x1f)))
652                 {
653                     builder.Append(t);
654                 }
655             }
656             return builder.ToString();
657         }
658         #endregion
659 
660         #region 防SQL注入
661         /// <summary>
662         /// 防SQL注入
663         /// </summary>
664         /// <param name="sql"></param>
665         /// <returns></returns>
666         public static string StripSQLInjection(string sql)
667         {
668             if (!String.IsNullOrEmpty(sql))
669             {
670                 string pattern = @"(\%27)|(\')|(\-\-)";
671                 string str2 = @"((\%27)|(\'))\s*((\%6F)|o|(\%4F))((\%72)|r|(\%52))";
672                 string str3 = @"\s+exec(\s|\+)+(s|x)p\w+";
673                 sql = Regex.Replace(sql, pattern, String.Empty, RegexOptions.IgnoreCase);
674                 sql = Regex.Replace(sql, str2, String.Empty, RegexOptions.IgnoreCase);
675                 sql = Regex.Replace(sql, str3, String.Empty, RegexOptions.IgnoreCase);
676             }
677             return sql;
678         }
679         #endregion
680 
681         #region 截取字符
682         public static string Trim(string stringTrim, int maxLength)
683         {
684             return Trim(stringTrim, maxLength, "...");
685         }
686 
687         public static string Trim(string rawString, int maxLength, string appendString)
688         {
689             if (String.IsNullOrEmpty(rawString) || (rawString.Length <= maxLength))
690             {
691                 return rawString;
692             }
693             if (Encoding.UTF8.GetBytes(rawString).Length <= (maxLength * 2))
694             {
695                 return rawString;
696             }
697             int length = Encoding.UTF8.GetBytes(appendString).Length;
698             StringBuilder builder = new StringBuilder();
699             int num3 = 0;
700             foreach (char ch in rawString)
701             {
702                 builder.Append(ch);
703                 num3 += Encoding.Default.GetBytes(new[] { ch }).Length;
704                 if (num3 >= ((maxLength * 2) - length))
705                 {
706                     break;
707                 }
708             }
709             return (builder + appendString);
710         }
711         #endregion
712 
713         #region 生成时间截
714         public static string GenerateTimeStamp()
715         {
716             TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
717             return Convert.ToInt64(ts.TotalSeconds).ToString();
718         }
719         #endregion
720 
721         #region 替换sql语句中的有问题符号
722         /// <summary>    
723         /// 替换sql语句中的有问题符号   
724         /// </summary>    
725         public static string ChkSQL(string str)
726         {
727             return (str == null) ? "" : str.Replace("'", "''");
728         }
729         #endregion
730 
731         #region 替换手机号和邮箱中间几位
732         /// <summary>  
733         /// 替换手机号中间四位为*  
734         /// </summary>  
735         /// <param name="phoneNo"></param>  
736         /// <returns></returns>  
737         public static string ReturnPhoneNO(string phoneNo)
738         {
739             Regex re = new Regex(@"(\d{3})(\d{4})(\d{4})", RegexOptions.None);
740             phoneNo = re.Replace(phoneNo, "$1****$3");
741             return phoneNo;
742         }
743 
744         /// <summary> 
745         /// 替换邮箱中间几位为*号  
746         /// </summary>  
747         /// <param name="Email"></param>  
748         /// <returns></returns>  
749         public static string ReturnEmail(string Email)
750         {
751             Regex re = new Regex(@"\w{3}(?=@\w+?.\S+)", RegexOptions.None);
752             Email = re.Replace(Email, "****");
753             return Email;
754         }
755         #endregion
756     }
757 }
View Code

 

posted on 2017-12-15 10:42  快舔包我很肥  阅读(146)  评论(0编辑  收藏  举报

导航