Be sure to install develop package and runtime library if needed since Visual Studio has 4.6.1 included. Signed-off-by: Syrone Wong <wong.syrone@gmail.com>
315 lines
8.2 KiB
C#
315 lines
8.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
|
|
#if EXPOSE_EVERYTHING || EXPOSE_STRINGEX
|
|
public
|
|
#endif
|
|
static partial class StringEx
|
|
{
|
|
#pragma warning disable 1591
|
|
|
|
public static StringComparison GlobalDefaultComparison { get; set; } = StringComparison.Ordinal;
|
|
|
|
[ThreadStatic]
|
|
private static StringComparison? _DefaultComparison;
|
|
public static StringComparison DefaultComparison
|
|
{
|
|
get { return _DefaultComparison ?? GlobalDefaultComparison; }
|
|
set { _DefaultComparison = value; }
|
|
}
|
|
|
|
#region basic String methods
|
|
|
|
public static bool IsNullOrEmpty(this string value)
|
|
=> string.IsNullOrEmpty(value);
|
|
|
|
public static bool IsNullOrWhiteSpace(this string value)
|
|
=> string.IsNullOrWhiteSpace(value);
|
|
|
|
public static bool IsWhiteSpace(this string value)
|
|
{
|
|
foreach (var c in value)
|
|
{
|
|
if (char.IsWhiteSpace(c)) continue;
|
|
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
#if !PCL
|
|
public static string IsInterned(this string value)
|
|
{
|
|
if (value == null)
|
|
throw new ArgumentNullException(nameof(value));
|
|
|
|
return string.IsInterned(value);
|
|
}
|
|
|
|
public static string Intern(this string value)
|
|
{
|
|
if (value == null)
|
|
throw new ArgumentNullException(nameof(value));
|
|
|
|
return string.Intern(value);
|
|
}
|
|
#endif
|
|
|
|
#if UNSAFE
|
|
public static unsafe string ToLowerForASCII(this string value)
|
|
{
|
|
if (value.IsNullOrWhiteSpace())
|
|
return value;
|
|
|
|
value = string.Copy(value);
|
|
fixed (char* low = value)
|
|
{
|
|
var end = low + value.Length;
|
|
for (var p = low; p < end; p++)
|
|
{
|
|
var c = *p;
|
|
if (c < 'A' || c > 'Z')
|
|
continue;
|
|
*p = (char)(c + 0x20);
|
|
}
|
|
}
|
|
return value;
|
|
}
|
|
|
|
public static unsafe string ToUpperForASCII(this string value)
|
|
{
|
|
if (value.IsNullOrWhiteSpace())
|
|
return value;
|
|
|
|
value = string.Copy(value);
|
|
fixed (char* low = value)
|
|
{
|
|
var end = low + value.Length;
|
|
for (var p = low; p < end; p++)
|
|
{
|
|
var c = *p;
|
|
if (c < 'a' || c > 'z')
|
|
continue;
|
|
*p = (char)(c - 0x20);
|
|
}
|
|
}
|
|
return value;
|
|
}
|
|
#else
|
|
public static string ToLowerForASCII(this string value)
|
|
{
|
|
if (value.IsNullOrWhiteSpace())
|
|
return value;
|
|
|
|
var sb = new StringBuilder(value.Length);
|
|
foreach (var c in value)
|
|
{
|
|
if (c < 'A' || c > 'Z')
|
|
sb.Append(c);
|
|
else
|
|
sb.Append((char)(c + 0x20));
|
|
}
|
|
return sb.ToString();
|
|
}
|
|
|
|
public static string ToUpperForASCII(this string value)
|
|
{
|
|
if (value.IsNullOrWhiteSpace())
|
|
return value;
|
|
|
|
var sb = new StringBuilder(value.Length);
|
|
foreach (var c in value)
|
|
{
|
|
if (c < 'a' || c > 'z')
|
|
sb.Append(c);
|
|
else
|
|
sb.Append((char)(c - 0x20));
|
|
}
|
|
return sb.ToString();
|
|
}
|
|
#endif
|
|
|
|
#endregion
|
|
|
|
#region comparing
|
|
|
|
#region Is
|
|
|
|
public static bool Is(this string a, string b)
|
|
=> string.Equals(a, b, DefaultComparison);
|
|
public static bool Is(this string a, string b, StringComparison comparisonType)
|
|
=> string.Equals(a, b, comparisonType);
|
|
|
|
#endregion
|
|
|
|
#region BeginWith
|
|
|
|
public static bool BeginWith(this string s, char c)
|
|
{
|
|
if (s.IsNullOrEmpty()) return false;
|
|
return s[0] == c;
|
|
}
|
|
public static bool BeginWithAny(this string s, IEnumerable<char> chars)
|
|
{
|
|
if (s.IsNullOrEmpty()) return false;
|
|
return chars.Contains(s[0]);
|
|
}
|
|
public static bool BeginWithAny(this string s, params char[] chars)
|
|
=> s.BeginWithAny(chars.AsEnumerable());
|
|
|
|
public static bool BeginWith(this string a, string b)
|
|
{
|
|
if (a == null || b == null) return false;
|
|
|
|
return a.StartsWith(b, DefaultComparison);
|
|
}
|
|
public static bool BeginWith(this string a, string b, StringComparison comparisonType)
|
|
{
|
|
if (a == null || b == null) return false;
|
|
|
|
return a.StartsWith(b, comparisonType);
|
|
}
|
|
#if !PCL
|
|
public static bool BeginWith(this string a, string b, bool ignoreCase, CultureInfo culture)
|
|
{
|
|
if (a == null || b == null) return false;
|
|
|
|
return a.StartsWith(b, ignoreCase, culture);
|
|
}
|
|
#endif
|
|
|
|
#endregion
|
|
|
|
#region FinishWith
|
|
|
|
public static bool FinishWith(this string s, char c)
|
|
{
|
|
if (s.IsNullOrEmpty()) return false;
|
|
return s.Last() == c;
|
|
}
|
|
public static bool FinishWithAny(this string s, IEnumerable<char> chars)
|
|
{
|
|
if (s.IsNullOrEmpty()) return false;
|
|
return chars.Contains(s.Last());
|
|
}
|
|
public static bool FinishWithAny(this string s, params char[] chars)
|
|
=> s.FinishWithAny(chars.AsEnumerable());
|
|
|
|
public static bool FinishWith(this string a, string b)
|
|
{
|
|
if (a == null || b == null) return false;
|
|
|
|
return a.EndsWith(b, DefaultComparison);
|
|
}
|
|
public static bool FinishWith(this string a, string b, StringComparison comparisonType)
|
|
{
|
|
if (a == null || b == null) return false;
|
|
|
|
return a.EndsWith(b, comparisonType);
|
|
}
|
|
#if !PCL
|
|
public static bool FinishWith(this string a, string b, bool ignoreCase, CultureInfo culture)
|
|
{
|
|
if (a == null || b == null) return false;
|
|
|
|
return a.EndsWith(b, ignoreCase, culture);
|
|
}
|
|
#endif
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
#region ToLines
|
|
|
|
public static IEnumerable<string> ToLines(this TextReader reader)
|
|
{
|
|
string line;
|
|
while ((line = reader.ReadLine()) != null)
|
|
yield return line;
|
|
}
|
|
public static IEnumerable<string> NonEmptyLines(this TextReader reader)
|
|
{
|
|
string line;
|
|
while ((line = reader.ReadLine()) != null)
|
|
{
|
|
if (line == "") continue;
|
|
yield return line;
|
|
}
|
|
}
|
|
public static IEnumerable<string> NonWhiteSpaceLines(this TextReader reader)
|
|
{
|
|
string line;
|
|
while ((line = reader.ReadLine()) != null)
|
|
{
|
|
if (line.IsWhiteSpace()) continue;
|
|
yield return line;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region others
|
|
|
|
private static readonly char[][] Quotes = new[]
|
|
{
|
|
"\"\"",
|
|
"''",
|
|
"“”",
|
|
"‘’",
|
|
"『』",
|
|
"「」",
|
|
"〖〗",
|
|
"【】",
|
|
}.Select(s => s.ToCharArray()).ToArray();
|
|
public static string Enquote(this string value)
|
|
{
|
|
if (value == null)
|
|
return "(null)";
|
|
|
|
foreach (var pair in Quotes)
|
|
{
|
|
if (value.IndexOfAny(pair) < 0)
|
|
return pair[0] + value + pair[1];
|
|
}
|
|
|
|
return '"' + value.Replace("\\", @"\\").Replace("\"", @"\""") + '"';
|
|
}
|
|
|
|
public static string Replace(this string value, string find, string rep, StringComparison comparsionType)
|
|
{
|
|
if (find.IsNullOrEmpty())
|
|
throw new ArgumentException(null, nameof(find));
|
|
if (rep == null)
|
|
rep = "";
|
|
if (value.IsNullOrEmpty())
|
|
return value;
|
|
|
|
var sb = new StringBuilder(value.Length);
|
|
|
|
var last = 0;
|
|
var len = find.Length;
|
|
var idx = value.IndexOf(find, DefaultComparison);
|
|
while (idx != -1)
|
|
{
|
|
sb.Append(value.Substring(last, idx - last));
|
|
sb.Append(rep);
|
|
idx += len;
|
|
|
|
last = idx;
|
|
idx = value.IndexOf(find, idx, comparsionType);
|
|
}
|
|
sb.Append(value.Substring(last));
|
|
|
|
return sb.ToString();
|
|
}
|
|
public static string ReplaceEx(this string value, string find, string rep)
|
|
=> value.Replace(find, rep, DefaultComparison);
|
|
|
|
#endregion
|
|
}
|