html的帮助类
1 /// <summary> 2 /// Represents a HTML helper 3 /// </summary> 4 public partial class HtmlHelper 5 { 6 #region Fields 7 private readonly static Regex paragraphStartRegex = new Regex("<p>", RegexOptions.IgnoreCase); 8 private readonly static Regex paragraphEndRegex = new Regex("</p>", RegexOptions.IgnoreCase); 9 //private static Regex ampRegex = new Regex("&(?!(?:#[0-9]{2,4};|[a-z0-9]+;))", RegexOptions.Compiled | RegexOptions.IgnoreCase); 10 11 #endregion 12 13 #region Utilities 14 15 private static string EnsureOnlyAllowedHtml(string text) 16 { 17 if (String.IsNullOrEmpty(text)) 18 return string.Empty; 19 20 const string allowedTags = "br,hr,b,i,u,a,div,ol,ul,li,blockquote,img,span,p,em,strong,font,pre,h1,h2,h3,h4,h5,h6,address,cite"; 21 22 var m = Regex.Matches(text, "<.*?>", RegexOptions.IgnoreCase); 23 for (int i = m.Count - 1; i >= 0; i--) 24 { 25 string tag = text.Substring(m[i].Index + 1, m[i].Length - 1).Trim().ToLower(); 26 27 if (!IsValidTag(tag, allowedTags)) 28 { 29 text = text.Remove(m[i].Index, m[i].Length); 30 } 31 } 32 33 return text; 34 } 35 36 private static bool IsValidTag(string tag, string tags) 37 { 38 string[] allowedTags = tags.Split(','); 39 if (tag.IndexOf("javascript") >= 0) return false; 40 if (tag.IndexOf("vbscript") >= 0) return false; 41 if (tag.IndexOf("onclick") >= 0) return false; 42 43 var endchars = new [] { ' ', '>', '/', ' ' }; 44 45 int pos = tag.IndexOfAny(endchars, 1); 46 if (pos > 0) tag = tag.Substring(0, pos); 47 if (tag[0] == '/') tag = tag.Substring(1); 48 49 foreach (string aTag in allowedTags) 50 { 51 if (tag == aTag) return true; 52 } 53 54 return false; 55 } 56 #endregion 57 58 #region Methods 59 /// <summary> 60 /// Formats the text 61 /// </summary> 62 /// <param name="text">Text</param> 63 /// <param name="stripTags">A value indicating whether to strip tags</param> 64 /// <param name="convertPlainTextToHtml">A value indicating whether HTML is allowed</param> 65 /// <param name="allowHtml">A value indicating whether HTML is allowed</param> 66 /// <param name="allowBBCode">A value indicating whether BBCode is allowed</param> 67 /// <param name="resolveLinks">A value indicating whether to resolve links</param> 68 /// <param name="addNoFollowTag">A value indicating whether to add "noFollow" tag</param> 69 /// <returns>Formatted text</returns> 70 public static string FormatText(string text, bool stripTags, 71 bool convertPlainTextToHtml, bool allowHtml, 72 bool allowBBCode, bool resolveLinks, bool addNoFollowTag) 73 { 74 75 if (String.IsNullOrEmpty(text)) 76 return string.Empty; 77 78 try 79 { 80 if (stripTags) 81 { 82 text = StripTags(text); 83 } 84 85 text = allowHtml ? EnsureOnlyAllowedHtml(text) : HttpUtility.HtmlEncode(text); 86 87 if (convertPlainTextToHtml) 88 { 89 text = ConvertPlainTextToHtml(text); 90 } 91 92 if (allowBBCode) 93 { 94 text = BBCodeHelper.FormatText(text, true, true, true, true, true, true, true); 95 } 96 97 if (resolveLinks) 98 { 99 text = ResolveLinksHelper.FormatText(text); 100 } 101 102 if (addNoFollowTag) 103 { 104 //add noFollow tag. not implemented 105 } 106 } 107 catch (Exception exc) 108 { 109 text = string.Format("Text cannot be formatted. Error: {0}", exc.Message); 110 } 111 return text; 112 } 113 114 /// <summary> 115 /// Strips tags 116 /// </summary> 117 /// <param name="text">Text</param> 118 /// <returns>Formatted text</returns> 119 public static string StripTags(string text) 120 { 121 if (String.IsNullOrEmpty(text)) 122 return string.Empty; 123 124 text = Regex.Replace(text, @"(>)( | )*(<)", "><"); 125 text = Regex.Replace(text, "(<[^>]*>)([^<]*)", "$2"); 126 text = Regex.Replace(text, "(&#x?[0-9]{2,4};|"|&| |<|>|€|©|®|‰|‡|†|‹|›|„|”|“|‚|’|‘|—|–|‏|‎|‍|‌| | | |˜|ˆ|Ÿ|š|Š)", "@"); 127 128 return text; 129 } 130 131 /// <summary> 132 /// replace anchor text (remove a tag from the following url <a href="http://example.com">Name</a> and output only the string "Name") 133 /// </summary> 134 /// <param name="text">Text</param> 135 /// <returns>Text</returns> 136 public static string ReplaceAnchorTags(string text) 137 { 138 if (String.IsNullOrEmpty(text)) 139 return string.Empty; 140 141 text = Regex.Replace(text, @"<a[^>]+>([^<]*(?:(?!</a)<[^<]*)*)</a>", "$1", RegexOptions.IgnoreCase); 142 return text; 143 } 144 145 /// <summary> 146 /// Converts plain text to HTML 147 /// </summary> 148 /// <param name="text">Text</param> 149 /// <returns>Formatted text</returns> 150 public static string ConvertPlainTextToHtml(string text) 151 { 152 if (String.IsNullOrEmpty(text)) 153 return string.Empty; 154 155 text = text.Replace(" ", "<br />"); 156 text = text.Replace(" ", "<br />"); 157 text = text.Replace(" ", "<br />"); 158 text = text.Replace(" ", " "); 159 text = text.Replace(" ", " "); 160 161 return text; 162 } 163 164 /// <summary> 165 /// Converts HTML to plain text 166 /// </summary> 167 /// <param name="text">Text</param> 168 /// <param name="decode">A value indicating whether to decode text</param> 169 /// <param name="replaceAnchorTags">A value indicating whether to replace anchor text (remove a tag from the following url <a href="http://example.com">Name</a> and output only the string "Name")</param> 170 /// <returns>Formatted text</returns> 171 public static string ConvertHtmlToPlainText(string text, 172 bool decode = false, bool replaceAnchorTags = false) 173 { 174 if (String.IsNullOrEmpty(text)) 175 return string.Empty; 176 177 if (decode) 178 text = HttpUtility.HtmlDecode(text); 179 180 text = text.Replace("<br>", " "); 181 text = text.Replace("<br >", " "); 182 text = text.Replace("<br />", " "); 183 text = text.Replace(" ", " "); 184 text = text.Replace(" ", " "); 185 186 if (replaceAnchorTags) 187 text = ReplaceAnchorTags(text); 188 189 return text; 190 } 191 192 /// <summary> 193 /// Converts text to paragraph 194 /// </summary> 195 /// <param name="text">Text</param> 196 /// <returns>Formatted text</returns> 197 public static string ConvertPlainTextToParagraph(string text) 198 { 199 if (String.IsNullOrEmpty(text)) 200 return string.Empty; 201 202 text = paragraphStartRegex.Replace(text, string.Empty);//把c#中的换行转换成html中的换行,源字符串中如果存在标签<p></p>,那么先转成c#中的换行符,最后把所有的c#换行符转换成<p></p>标签的字符串 203 text = paragraphEndRegex.Replace(text, " "); 204 text = text.Replace(" ", " ").Replace(" ", " "); 205 text = text + " "; 206 text = text.Replace(" ", " "); 207 var strArray = text.Split(new [] { ' ' }); 208 var builder = new StringBuilder(); 209 foreach (string str in strArray) 210 { 211 if ((str != null) && (str.Trim().Length > 0)) 212 { 213 builder.AppendFormat("<p>{0}</p> ", str); 214 } 215 } 216 return builder.ToString(); 217 } 218 #endregion 219 }
锚标签的帮助类
1 /// <summary> 2 /// Represents a ResolveLinks helper 3 /// </summary> 4 public partial class ResolveLinksHelper 5 { 6 #region Fields 7 /// <summary> 8 /// The regular expression used to parse links. 9 /// </summary> 10 private static readonly Regex regex = new Regex("((http://|https://|www\.)([A-Z0-9.\-]{1,})\.[0-9A-Z?;~&\(\)#,=\-_\./\+]{2,})", RegexOptions.Compiled | RegexOptions.IgnoreCase); 11 private const string link = "<a href="{0}{1}" rel="nofollow">{2}</a>"; 12 private const int MAX_LENGTH = 50; 13 #endregion 14 15 #region Utilities 16 17 /// <summary> 18 /// Shortens any absolute URL to a specified maximum length 19 /// </summary> 20 private static string ShortenUrl(string url, int max) 21 { 22 if (url.Length <= max) 23 return url; 24 25 // Remove the protocal 26 int startIndex = url.IndexOf("://"); 27 if (startIndex > -1) 28 url = url.Substring(startIndex + 3); 29 30 if (url.Length <= max) 31 return url; 32 33 // Compress folder structure 34 int firstIndex = url.IndexOf("/") + 1; 35 int lastIndex = url.LastIndexOf("/"); 36 if (firstIndex < lastIndex) 37 { 38 url = url.Remove(firstIndex, lastIndex - firstIndex); 39 url = url.Insert(firstIndex, "..."); 40 } 41 42 if (url.Length <= max) 43 return url; 44 45 // Remove URL parameters 46 int queryIndex = url.IndexOf("?"); 47 if (queryIndex > -1) 48 url = url.Substring(0, queryIndex); 49 50 if (url.Length <= max) 51 return url; 52 53 // Remove URL fragment 54 int fragmentIndex = url.IndexOf("#"); 55 if (fragmentIndex > -1) 56 url = url.Substring(0, fragmentIndex); 57 58 if (url.Length <= max) 59 return url; 60 61 // Compress page 62 firstIndex = url.LastIndexOf("/") + 1; 63 lastIndex = url.LastIndexOf("."); 64 if (lastIndex - firstIndex > 10) 65 { 66 string page = url.Substring(firstIndex, lastIndex - firstIndex); 67 int length = url.Length - max + 3; 68 if (page.Length > length) 69 url = url.Replace(page, "..." + page.Substring(length)); 70 } 71 72 return url; 73 } 74 #endregion 75 76 #region Methods 77 /// <summary> 78 /// Formats the text 79 /// </summary> 80 /// <param name="text">Text</param> 81 /// <returns>Formatted text</returns> 82 public static string FormatText(string text) 83 { 84 if (String.IsNullOrEmpty(text)) 85 return string.Empty; 86 87 var info = CultureInfo.InvariantCulture; 88 foreach (Match match in regex.Matches(text)) 89 { 90 if (!match.Value.Contains("://")) 91 { 92 text = text.Replace(match.Value, string.Format(info, link, "http://", match.Value, ShortenUrl(match.Value, MAX_LENGTH))); 93 } 94 else 95 { 96 text = text.Replace(match.Value, string.Format(info, link, string.Empty, match.Value, ShortenUrl(match.Value, MAX_LENGTH))); 97 } 98 } 99 100 return text; 101 } 102 #endregion 103 }
bbcode的帮助类
1 /// <summary> 2 /// Represents a BBCode helper 3 /// </summary> 4 public partial class BBCodeHelper 5 { 6 #region Fields 7 private static readonly Regex regexBold = new Regex(@"[b](.+?)[/b]", RegexOptions.Compiled | RegexOptions.IgnoreCase); 8 private static readonly Regex regexItalic = new Regex(@"[i](.+?)[/i]", RegexOptions.Compiled | RegexOptions.IgnoreCase); 9 private static readonly Regex regexUnderLine = new Regex(@"[u](.+?)[/u]", RegexOptions.Compiled | RegexOptions.IgnoreCase); 10 private static readonly Regex regexUrl1 = new Regex(@"[url=([^]]+)]([^]]+)[/url]", RegexOptions.Compiled | RegexOptions.IgnoreCase); 11 private static readonly Regex regexUrl2 = new Regex(@"[url](.+?)[/url]", RegexOptions.Compiled | RegexOptions.IgnoreCase); 12 private static readonly Regex regexQuote = new Regex(@"[quote=(.+?)](.+?)[/quote]", RegexOptions.Compiled | RegexOptions.IgnoreCase); 13 private static readonly Regex regexImg = new Regex(@"[img](.+?)[/img]", RegexOptions.Compiled | RegexOptions.IgnoreCase); 14 15 #endregion 16 17 #region Methods 18 /// <summary> 19 /// Formats the text 20 /// </summary> 21 /// <param name="text">Text</param> 22 /// <param name="replaceBold">A value indicating whether to replace Bold</param> 23 /// <param name="replaceItalic">A value indicating whether to replace Italic</param> 24 /// <param name="replaceUnderline">A value indicating whether to replace Underline</param> 25 /// <param name="replaceUrl">A value indicating whether to replace URL</param> 26 /// <param name="replaceCode">A value indicating whether to replace Code</param> 27 /// <param name="replaceQuote">A value indicating whether to replace Quote</param> 28 /// <param name="replaceImg">A value indicating whether to replace Img</param> 29 /// <returns>Formatted text</returns> 30 public static string FormatText(string text, bool replaceBold, bool replaceItalic, 31 bool replaceUnderline, bool replaceUrl, bool replaceCode, bool replaceQuote, bool replaceImg) 32 { 33 if (String.IsNullOrEmpty(text)) 34 return string.Empty; 35 36 if (replaceBold) 37 { 38 // format the bold tags: [b][/b] 39 // becomes: <strong></strong> 40 text = regexBold.Replace(text, "<strong>$1</strong>"); 41 } 42 43 if (replaceItalic) 44 { 45 // format the italic tags: [i][/i] 46 // becomes: <em></em> 47 text = regexItalic.Replace(text, "<em>$1</em>"); 48 } 49 50 if (replaceUnderline) 51 { 52 // format the underline tags: [u][/u] 53 // becomes: <u></u> 54 text = regexUnderLine.Replace(text, "<u>$1</u>"); 55 } 56 57 if (replaceUrl) 58 { 59 var newWindow = EngineContext.Current.Resolve<CommonSettings>().BbcodeEditorOpenLinksInNewWindow; 60 // format the url tags: [url=http://www.nopCommerce.com]my site[/url] 61 // becomes: <a href="http://www.nopCommerce.com">my site</a> 62 text = regexUrl1.Replace(text, string.Format("<a href="$1" rel="nofollow"{0}>$2</a>", newWindow ? " target=_blank" : "")); 63 64 // format the url tags: [url]http://www.nopCommerce.com[/url] 65 // becomes: <a href="http://www.nopCommerce.com">http://www.nopCommerce.com</a> 66 text = regexUrl2.Replace(text, string.Format("<a href="$1" rel="nofollow"{0}>$1</a>", newWindow ? " target=_blank" : "")); 67 } 68 69 if (replaceQuote) 70 { 71 while (regexQuote.IsMatch(text)) 72 text = regexQuote.Replace(text, "<b>$1 wrote:</b><div class="quote">$2</div>"); 73 } 74 75 if (replaceCode) 76 { 77 text = CodeFormatHelper.FormatTextSimple(text); 78 } 79 80 if (replaceImg) 81 { 82 // format the img tags: [img]http://www.nopCommerce.com/Content/Images/Image.jpg[/img] 83 // becomes: <img src="http://www.nopCommerce.com/Content/Images/Image.jpg"> 84 text = regexImg.Replace(text, "<img src="$1" class="user-posted-image" alt="">"); 85 } 86 return text; 87 } 88 89 /// <summary> 90 /// Removes all quotes from string 91 /// </summary> 92 /// <param name="str">Source string</param> 93 /// <returns>string</returns> 94 public static string RemoveQuotes(string str) 95 { 96 str = Regex.Replace(str, @"[quote=(.+?)]", String.Empty, RegexOptions.Compiled | RegexOptions.IgnoreCase); 97 str = Regex.Replace(str, @"[/quote]", String.Empty, RegexOptions.Compiled | RegexOptions.IgnoreCase); 98 return str; 99 } 100 101 #endregion 102 }
类型转换
public static int StrToInt(object obj, int? defaultVal) { try { return Convert.ToInt32(obj); } catch { return defaultVal ?? 0; } }