public static class StringExtensions
{
public static string [] ToPiece( this string text, int maxLength)
{
int pieces = ( int )Math.Ceiling(text.Length / ( double )maxLength);
string [] result = new string [pieces];
for ( int i = 0 ; i < pieces - 1 ; i ++ )
{
result[i] = text.Substring(i * maxLength, maxLength);
}
result[pieces - 1 ] = text.Substring((pieces - 1 ) * maxLength);
return result;
}
public static string Join( this string [] values, string joinText)
{
StringBuilder result = new StringBuilder();
if (values.Length == 0 ) return string .Empty;
result.Append(values[ 0 ]);
for ( int i = 1 ; i < values.Length; i ++ )
{
result.Append(joinText);
result.Append(values[i]);
}
return result.ToString();
}
public static string TrimWithElipsis( this string text, int length)
{
if (text.Length <= length) return text;
return text.Substring( 0 , length) + " ... " ;
}
/// <summary>
/// replacement for String.Format
/// </summary>
public static string With( this string format, params object [] args)
{
return string .Format(format, args);
}
/// <summary>
/// prettily renders property names
/// </summary>
/// <param name="text"></param>
/// <returns></returns>
public static string Pretty( this string text)
{
return DeCamel(text).Replace( " _ " , " " );
}
public static void PrettyTest()
{
Console.WriteLine( " hello_worldIAmYourNemesis " .Pretty());
}
/// <summary>
/// turns HelloWorld into Hello World
/// </summary>
/// <param name="text"></param>
/// <returns></returns>
public static string DeCamel( this string text)
{
return Regex.Replace(text, @" ([A-Z]) " , @" $& " ).Trim();
}
public static void DeCamelTest()
{
Console.WriteLine( " HelloWorldIAmYourNemesis " .DeCamel());
}
public static string CreateSlug( this string source)
{
var regex = new Regex( @" ([^a-z0-9\-]?) " );
string slug = "" ;
if ( ! string .IsNullOrEmpty(source))
{
slug = source.Trim().ToLower();
slug = slug.Replace( ' ' , ' - ' );
slug = slug.Replace( " --- " , " - " );
slug = slug.Replace( " -- " , " - " );
if (regex != null )
slug = regex.Replace(slug, "" );
if (slug.Length * 2 < source.Length)
return "" ;
if (slug.Length > 100 )
slug = slug.Substring( 0 , 100 );
}
return slug;
}
public static string Truncate( this string src, int size)
{
if (src.Length < size)
return src;
else
return src.Substring( 0 , size); // SubString 不包含size位置的
}
public static string EncryptMD5( this string Value)
{
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
byte [] valueArray = System.Text.Encoding.ASCII.GetBytes(Value);
valueArray = md5.ComputeHash(valueArray);
StringBuilder sb = new StringBuilder();
for ( int i = 0 ; i < valueArray.Length; i ++ )
sb.Append(valueArray[i].ToString( " x2 " ).ToLower());
return sb.ToString();
}
public static bool VerifyMD5Hash( this string value, string target)
{
string input = value.EncryptMD5();
if (input.Equals(target))
return true ;
return false ;
}
public static string CleanHtmlTags( this string s)
{
return s.CleanHtmlTags( null );
}
private static readonly Regex tagRegex = new Regex( " <[^<>]*> " , RegexOptions.Compiled | RegexOptions.Singleline);
public static string CleanHtmlTags( this string s, string exceptionPattern)
{
if ( ! string .IsNullOrEmpty(exceptionPattern))
return
new Regex( string .Format( " <(?!{0})[^<>]*> " , exceptionPattern),
RegexOptions.Compiled | RegexOptions.Singleline).Replace(s, "" );
return tagRegex.Replace(s, "" );
}
private static readonly Regex spaceRegex = new Regex( @" \s+ " , RegexOptions.Compiled | RegexOptions.Singleline);
public static string CleanWhitespace( this string s)
{
return spaceRegex.Replace(s, " " );
}
public static string IsRequired( this string s)
{
if ( string .IsNullOrEmpty(s))
{
// throw new ValidationException(string.Format("String is required: {0}", s));
throw new Exception( string .Format( " String is required: {0} " , s));
}
return s;
}
private static readonly Regex nonWordCharsRegex = new Regex( @" [^\w]+ " , RegexOptions.Compiled | RegexOptions.Singleline);
public static string CleanCssClassName( this string s)
{
return nonWordCharsRegex.Replace(s, " _ " ).ToLower(System.Globalization.CultureInfo.CurrentCulture);
}
public static string CleanText( this string s)
{
if (s == null ) return null ;
return HttpUtility.HtmlEncode(s);
}
public static string CleanHtml( this string s)
{
// AntiXss library from Microsoft
// ( http://antixss.codeplex.com )
string encodedText = HttpUtility.HtmlEncode(s);
// convert line breaks into an html break tag
return encodedText.Replace( " " , " <br /> " );
}
public static string CleanForQueryString( this string s)
{
return HttpUtility.UrlEncode(s);
}
public static string CleanAttribute( this string s)
{
return HttpUtility.HtmlAttributeEncode(s);
}
// todo: (nheskew) rename to something more generic (CleanAttributeALittle?) because not everything needs
// the cleaning power of CleanAttribute (everything should but AntiXss.HtmlAttributeEncode encodes
// *everyting* incl. white space :|) so attributes can get really long...but then my only current worry is around
// the description meta tag. Attributes from untrusted sources *do* need the current CleanAttribute...
public static string CleanHref( this string s)
{
return HttpUtility.HtmlAttributeEncode(s);
}
public static string CleanCommentBody( this string s)
{
return s.CleanHtmlTags().CleanHtml().AutoAnchor();
}
private static readonly Regex uriRegex = new Regex( " (^|[^\\w'\ " ] | \\G)( ?< uri > ( ? :https ?| ftp)( ? : & # 58 ; | :)( ? : & # 47 ; & # 47 ; | // )(?:[^./\\s'\"<)\\]]+\\.)+[^./\\s'\"<)\\]]+(?:(?:/|/).*?)?)(?:[\\s\\.,\\)\\]'\"]?(?:\\s|\\.|\\)|\\]|,|<|$))", RegexOptions.Compiled | RegexOptions.IgnoreCase);
public static string AutoAnchor( this string s)
{
MatchCollection uriMatches = uriRegex.Matches(s);
foreach (Match uriMatch in uriMatches)
{
string encodedUri = uriMatch.Groups[ " uri " ].Value;
if ( ! string .IsNullOrEmpty(encodedUri))
{
string uri = HttpUtility.HtmlDecode(encodedUri);
s = s.Replace(encodedUri, string .Format( " <a href=\ " { 0 }\ " >{1}</a> " , uri.CleanHref(), uri.CleanText()));
}
}
return s;
}
public static string Shorten( this string s, int characterCount)
{
string text = ! string .IsNullOrEmpty(s) ? s.CleanHtmlTags().CleanWhitespace() : "" ;
if ( ! string .IsNullOrEmpty(text) && characterCount > 0 && text.Length > characterCount)
{
text = text.Substring( 0 , characterCount);
}
return text;
}
public static string Ellipsize( this string s, int characterCount, Func < string , string > processStringPart)
{
return s.Ellipsize(characterCount, processStringPart, "  … " );
}
public static string Ellipsize( this string s, int characterCount, Func < string , string > processStringPart, string ellipsis)
{
++ characterCount;
string text = ! string .IsNullOrEmpty(s) ? s.CleanHtmlTags().CleanWhitespace() : "" ;
if ( string .IsNullOrEmpty(text) || characterCount < 1 || text.Length <= characterCount)
return text;
string [] words = text.Substring( 0 , characterCount).Split( ' ' );
return processStringPart( string .Join( " " , words.Take(words.Length - 1 ).ToArray())) + ellipsis;
}
public static string EllipsizeUri( this string s, int characterCount, Func < string , string > processStringPart)
{
return s.EllipsizeUri(characterCount, processStringPart, "  …  " );
}
// info: (nheskew) ellipsis length hard-coded to the default decoded
public static string EllipsizeUri( this string s, int characterCount, Func < string , string > processStringPart, string ellipsis)
{
Uri uri;
int ellipsisLength = 3 ; // not really accurate considering the use of the hellip character
// return because we're not going to mess with the "URI" string
if ( string .IsNullOrEmpty(s) ||
characterCount < 1 ||
s.Length <= characterCount ||
! Uri.TryCreate(s, UriKind.Absolute, out uri))
return processStringPart(s);
string start = uri.Scheme + " :// " ;
string end = uri.Segments.LastOrDefault() ?? "" ;
if ( ! string .IsNullOrEmpty(uri.Query))
end = end + " ? " + ellipsis;
// need to ellipsize the host name because the string is already getting too long
if (start.Length + uri.Host.Length + ellipsisLength + end.Length > characterCount)
{
string host = uri.Host;
int endLength = characterCount - (start.Length + host.Length + ellipsisLength);
if (endLength < 0 )
{
int hostSubLength = (characterCount - (start.Length + ellipsisLength * 2 )) / 2 ; // two ellilpsis. host and end
host = hostSubLength > 0
? processStringPart(host.Substring( 0 , hostSubLength)) +
ellipsis +
processStringPart(host.Substring(host.Length - hostSubLength, hostSubLength))
: "" ;
endLength = 0 ;
}
else
{
host = processStringPart(host);
}
return processStringPart(start) +
host +
ellipsis +
(endLength > 0 ? processStringPart(end.Substring(end.Length - endLength, endLength)) : "" );
}
start = start + uri.Host;
// add as many path segments as we can
var pathParts = uri.Segments.Take(uri.Segments.Length - 1 );
foreach ( string pathPart in pathParts)
{
if (start.Length + pathPart.Length + ellipsisLength + end.Length > characterCount)
return processStringPart(start) + ellipsis + processStringPart(end);
start = start + pathPart;
}
return processStringPart(start + end);
}
public static string ComputeHash( this string value)
{
if ( ! string .IsNullOrEmpty(value))
{
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
byte [] data = Encoding.ASCII.GetBytes(value);
string hash = "" ;
data = md5.ComputeHash(data);
for ( int i = 0 ; i < data.Length; i ++ )
hash += data[i].ToString( " x2 " );
return hash;
}
return value;
}
public static bool GuidTryParse( this string s, out Guid result)
{
if (s == null )
{
throw new ArgumentNullException( " s " );
}
try
{
result = new Guid(s);
return true ;
}
catch (FormatException)
{
result = Guid.Empty;
return false ;
}
catch (OverflowException)
{
result = Guid.Empty;
return false ;
}
}
public static string GetFileText( this string virtualPath)
{
return virtualPath.GetFileText( new HttpContextWrapper(HttpContext.Current));
}
public static string GetFileText( this string virtualPath, HttpContextBase httpContext)
{
string path = httpContext.Server.MapPath(virtualPath);
if (File.Exists(path))
return File.ReadAllText(path);
return null ;
}
public static string Skip( this string str, char word)
{
return str.Replace(word, ' ' );
}
}