├── StringEx.CS.nuspec └── StringEx.cs /StringEx.CS.nuspec: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | StringEx.CS 5 | 0.3.1 6 | Licshee 7 | https://github.com/OmniKits/StringEx 8 | false 9 | true 10 | - 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /StringEx.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text; 7 | 8 | #if EXPOSE_EVERYTHING || EXPOSE_STRINGEX 9 | public 10 | #endif 11 | static partial class StringEx 12 | { 13 | #pragma warning disable 1591 14 | 15 | public static StringComparison GlobalDefaultComparison { get; set; } = StringComparison.Ordinal; 16 | 17 | [ThreadStatic] 18 | private static StringComparison? _DefaultComparison; 19 | public static StringComparison DefaultComparison 20 | { 21 | get { return _DefaultComparison ?? GlobalDefaultComparison; } 22 | set { _DefaultComparison = value; } 23 | } 24 | 25 | #region basic String methods 26 | 27 | public static bool IsNullOrEmpty(this string value) 28 | => string.IsNullOrEmpty(value); 29 | 30 | public static bool IsNullOrWhiteSpace(this string value) 31 | => string.IsNullOrWhiteSpace(value); 32 | 33 | public static bool IsWhiteSpace(this string value) 34 | { 35 | foreach (var c in value) 36 | { 37 | if (char.IsWhiteSpace(c)) continue; 38 | 39 | return false; 40 | } 41 | return true; 42 | } 43 | 44 | #if !PCL 45 | public static string IsInterned(this string value) 46 | { 47 | if (value == null) 48 | throw new ArgumentNullException(nameof(value)); 49 | 50 | return string.IsInterned(value); 51 | } 52 | 53 | public static string Intern(this string value) 54 | { 55 | if (value == null) 56 | throw new ArgumentNullException(nameof(value)); 57 | 58 | return string.Intern(value); 59 | } 60 | #endif 61 | 62 | #if UNSAFE 63 | public static unsafe string ToLowerForASCII(this string value) 64 | { 65 | if (value.IsNullOrWhiteSpace()) 66 | return value; 67 | 68 | value = string.Copy(value); 69 | fixed (char* low = value) 70 | { 71 | var end = low + value.Length; 72 | for (var p = low; p < end; p++) 73 | { 74 | var c = *p; 75 | if (c < 'A' || c > 'Z') 76 | continue; 77 | *p = (char)(c + 0x20); 78 | } 79 | } 80 | return value; 81 | } 82 | 83 | public static unsafe string ToUpperForASCII(this string value) 84 | { 85 | if (value.IsNullOrWhiteSpace()) 86 | return value; 87 | 88 | value = string.Copy(value); 89 | fixed (char* low = value) 90 | { 91 | var end = low + value.Length; 92 | for (var p = low; p < end; p++) 93 | { 94 | var c = *p; 95 | if (c < 'a' || c > 'z') 96 | continue; 97 | *p = (char)(c - 0x20); 98 | } 99 | } 100 | return value; 101 | } 102 | #else 103 | public static string ToLowerForASCII(this string value) 104 | { 105 | if (value.IsNullOrWhiteSpace()) 106 | return value; 107 | 108 | var sb = new StringBuilder(value.Length); 109 | foreach (var c in value) 110 | { 111 | if (c < 'A' || c > 'Z') 112 | sb.Append(c); 113 | else 114 | sb.Append((char)(c + 0x20)); 115 | } 116 | return sb.ToString(); 117 | } 118 | 119 | public static string ToUpperForASCII(this string value) 120 | { 121 | if (value.IsNullOrWhiteSpace()) 122 | return value; 123 | 124 | var sb = new StringBuilder(value.Length); 125 | foreach (var c in value) 126 | { 127 | if (c < 'a' || c > 'z') 128 | sb.Append(c); 129 | else 130 | sb.Append((char)(c - 0x20)); 131 | } 132 | return sb.ToString(); 133 | } 134 | #endif 135 | 136 | #endregion 137 | 138 | #region comparing 139 | 140 | #region Is 141 | 142 | public static bool Is(this string a, string b) 143 | => string.Equals(a, b, DefaultComparison); 144 | public static bool Is(this string a, string b, StringComparison comparisonType) 145 | => string.Equals(a, b, comparisonType); 146 | 147 | #endregion 148 | 149 | #region BeginWith 150 | 151 | public static bool BeginWith(this string s, char c) 152 | { 153 | if (s.IsNullOrEmpty()) return false; 154 | return s[0] == c; 155 | } 156 | public static bool BeginWithAny(this string s, IEnumerable chars) 157 | { 158 | if (s.IsNullOrEmpty()) return false; 159 | return chars.Contains(s[0]); 160 | } 161 | public static bool BeginWithAny(this string s, params char[] chars) 162 | => s.BeginWithAny(chars.AsEnumerable()); 163 | 164 | public static bool BeginWith(this string a, string b) 165 | { 166 | if (a == null || b == null) return false; 167 | 168 | return a.StartsWith(b, DefaultComparison); 169 | } 170 | public static bool BeginWith(this string a, string b, StringComparison comparisonType) 171 | { 172 | if (a == null || b == null) return false; 173 | 174 | return a.StartsWith(b, comparisonType); 175 | } 176 | #if !PCL 177 | public static bool BeginWith(this string a, string b, bool ignoreCase, CultureInfo culture) 178 | { 179 | if (a == null || b == null) return false; 180 | 181 | return a.StartsWith(b, ignoreCase, culture); 182 | } 183 | #endif 184 | 185 | #endregion 186 | 187 | #region FinishWith 188 | 189 | public static bool FinishWith(this string s, char c) 190 | { 191 | if (s.IsNullOrEmpty()) return false; 192 | return s.Last() == c; 193 | } 194 | public static bool FinishWithAny(this string s, IEnumerable chars) 195 | { 196 | if (s.IsNullOrEmpty()) return false; 197 | return chars.Contains(s.Last()); 198 | } 199 | public static bool FinishWithAny(this string s, params char[] chars) 200 | => s.FinishWithAny(chars.AsEnumerable()); 201 | 202 | public static bool FinishWith(this string a, string b) 203 | { 204 | if (a == null || b == null) return false; 205 | 206 | return a.EndsWith(b, DefaultComparison); 207 | } 208 | public static bool FinishWith(this string a, string b, StringComparison comparisonType) 209 | { 210 | if (a == null || b == null) return false; 211 | 212 | return a.EndsWith(b, comparisonType); 213 | } 214 | #if !PCL 215 | public static bool FinishWith(this string a, string b, bool ignoreCase, CultureInfo culture) 216 | { 217 | if (a == null || b == null) return false; 218 | 219 | return a.EndsWith(b, ignoreCase, culture); 220 | } 221 | #endif 222 | 223 | #endregion 224 | 225 | #endregion 226 | 227 | #region ToLines 228 | 229 | public static IEnumerable ToLines(this TextReader reader) 230 | { 231 | string line; 232 | while ((line = reader.ReadLine()) != null) 233 | yield return line; 234 | } 235 | public static IEnumerable NonEmptyLines(this TextReader reader) 236 | { 237 | string line; 238 | while ((line = reader.ReadLine()) != null) 239 | { 240 | if (line == "") continue; 241 | yield return line; 242 | } 243 | } 244 | public static IEnumerable NonWhiteSpaceLines(this TextReader reader) 245 | { 246 | string line; 247 | while ((line = reader.ReadLine()) != null) 248 | { 249 | if (line.IsWhiteSpace()) continue; 250 | yield return line; 251 | } 252 | } 253 | 254 | #endregion 255 | 256 | #region others 257 | 258 | private static readonly char[][] Quotes = new[] 259 | { 260 | "\"\"", 261 | "''", 262 | "“”", 263 | "‘’", 264 | "『』", 265 | "「」", 266 | "〖〗", 267 | "【】", 268 | }.Select(s => s.ToCharArray()).ToArray(); 269 | public static string Enquote(this string value) 270 | { 271 | if (value == null) 272 | return "(null)"; 273 | 274 | foreach (var pair in Quotes) 275 | { 276 | if (value.IndexOfAny(pair) < 0) 277 | return pair[0] + value + pair[1]; 278 | } 279 | 280 | return '"' + value.Replace("\\", @"\\").Replace("\"", @"\""") + '"'; 281 | } 282 | 283 | public static string Replace(this string value, string find, string rep, StringComparison comparsionType) 284 | { 285 | if (find.IsNullOrEmpty()) 286 | throw new ArgumentException(null, nameof(find)); 287 | if (rep == null) 288 | rep = ""; 289 | if (value.IsNullOrEmpty()) 290 | return value; 291 | 292 | var sb = new StringBuilder(value.Length); 293 | 294 | var last = 0; 295 | var len = find.Length; 296 | var idx = value.IndexOf(find, DefaultComparison); 297 | while (idx != -1) 298 | { 299 | sb.Append(value.Substring(last, idx - last)); 300 | sb.Append(rep); 301 | idx += len; 302 | 303 | last = idx; 304 | idx = value.IndexOf(find, idx, comparsionType); 305 | } 306 | sb.Append(value.Substring(last)); 307 | 308 | return sb.ToString(); 309 | } 310 | public static string ReplaceEx(this string value, string find, string rep) 311 | => value.Replace(find, rep, DefaultComparison); 312 | 313 | #endregion 314 | } 315 | --------------------------------------------------------------------------------