using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace EasyDevCore.Common
{
///
/// String extension helper
///
public static class StringExtensions
{
///
/// Ins the specified string comparison.
///
/// The input.
/// One of the enumeration values that specifies how the strings will be compared.
/// The arguments.
///
public static bool In(this string input, StringComparison comparisionType, params string[] args)
{
if (input == null) return false;
foreach (string value in args)
{
if (!input.Equals(value))
continue;
return true;
}
return false;
}
///
/// Determines whether the specified arguments has any.
///
/// The input.
/// The arguments.
///
/// true if the specified arguments has any; otherwise, false.
///
public static bool HasAny(this string input, params string[] args)
{
foreach(var p in args)
{
if (input.IndexOf(p) > -1) return true;
}
return false;
}
///
/// Determines whether the specified comparison has any.
///
/// The input.
/// The comparison.
/// The arguments.
///
/// true if the specified comparison has any; otherwise, false.
///
public static bool HasAny(this string input, StringComparison comparison, params string[] args)
{
foreach (var p in args)
{
if (input.IndexOf(p, comparison) > -1) return true;
}
return false;
}
///
/// Determines whether [is unicode string] [the specified input].
///
/// The input.
///
/// true if [is unicode string] [the specified input]; otherwise, false.
///
public static bool IsUnicode(this string input)
{
return input.ToCharArray().Any(c => c > 255);
}
///
/// Removes all leading occurrences of whitespace of input string
///
/// The input.
///
public static string LTrim(this string input)
{
return input.TrimStart(new char[] { ' ' });
}
///
/// Removes all occurrences of whitespace of the end of the input string
///
/// The input.
///
public static string RTrim(this string input)
{
return input.TrimEnd(new char[] { ' ' });
}
///
/// Lefts the specified length.
///
/// The input.
/// The length.
///
public static string Left(this string input, int len) => (input == null || input.Length <= len) ? input : input.Substring(0, len);
///
/// Rights the specified length.
///
/// The input.
/// The length.
///
public static string Right(this string input, int len) => (input == null || input.Length <= len) ? input : input.Substring(input.Length - len, len);
///
/// Replaces with case style.
///
/// The text.
/// The old value.
/// The new value.
/// Maximum length of the match.
///
public static string ReplaceCaseStyle(this string text, string oldValue, string newValue, int maxMatchLength = 0)
{
var caseReplacement = TransferCaseStyle(oldValue, newValue);
return text.Replace(oldValue, caseReplacement);
}
///
/// Transfers the case style.
///
/// The match.
/// The replacement.
/// Maximum length of the match.
///
public static string TransferCaseStyle(string match, string replacement, int maxMatchLength = 0)
{
char[] replacementChars = replacement.ToCharArray();
if(maxMatchLength == 0)
{
maxMatchLength = Math.Min(match.Length, replacement.Length);
}
for (int i = 0; i < maxMatchLength; i++)
{
if (char.IsLower(match[i]))
replacementChars[i] = char.ToLower(replacementChars[i]);
else if (char.IsUpper(match[i]))
replacementChars[i] = char.ToUpper(replacementChars[i]);
}
return new string(replacementChars);
}
///
/// Regexes the get match values.
///
/// The input.
/// The patterns.
/// (Key = Match Value, Value = Group Name)
public static Dictionary RegexGetMatchValues(this string input, string patterns)
{
Dictionary matchValues = new();
Regex re = new Regex(patterns);
var groupNames = re.GetGroupNames().Where(x => !(x[0] >= (byte)'0' && x[0] <= (byte)'9')).ToArray();
var matches = re.Matches(input);
foreach (Match m in matches.AsParallel())
{
foreach (var gn in groupNames)
{
var mg = m.Groups[gn];
if (mg.Success)
{
var value = mg.Value;
if (!matchValues.ContainsKey(value))
{
matchValues.Add(value, gn);
}
}
}
}
return matchValues;
}
///
/// Regexes the group match.
///
/// The input.
/// The patterns.
/// The match handler is Func(Group match, string groupname, string replactedText).
public static void RegexGroupMatch(this string input, string patterns, Action matchHandler)
{
Regex re = new Regex(patterns);
var groupNames = re.GetGroupNames().Where(x => !(x[0] >= (byte)'0' && x[0] <= (byte)'9')).ToArray();
var matches = re.Matches(input);
foreach (Match m in matches.AsParallel())
{
foreach (var gn in groupNames)
{
var mg = m.Groups[gn];
if (mg.Success)
{
matchHandler(mg);
}
}
}
}
///
/// Regexes the group replace.
///
/// The input.
/// The patterns.
/// The match handler is Func(Group match, string groupname, string replactedText).
///
public static string RegexGroupReplace(this string input, string patterns, Func matchHandler)
{
Regex re = new Regex(patterns);
var groupNames = re.GetGroupNames().Where(x => !(x[0] >= (byte)'0' && x[0] <= (byte)'9')).ToArray();
return re.Replace(input, (MatchEvaluator)((m) =>
{
foreach (var gn in groupNames)
{
var mg = m.Groups[gn];
if (mg.Success)
{
return matchHandler(mg, gn);
}
}
return m.Value;
}));
}
///
/// Substitudes the specified input.
///
/// The input.
/// The index.
/// The length.
/// The replaced text.
///
public static string Substitude(this string input, int index, int length, string replacedText)
{
return input.Substring(0, index) + replacedText + (index + length > input.Length ? "" : input.Substring(index + length));
}
///
/// Substitudes the specified input.
///
/// The input.
/// The index.
/// The replaced text.
///
public static string Substitude(this string input, int index, string replacedText)
{
return input.Substring(0, index) + replacedText + (index + replacedText.Length > input.Length ? "" : input.Substring(index + replacedText.Length));
}
///
/// Splits the string.
///
/// The input.
/// The seperator.
/// The split options.
/// if set to true [trim space].
///
public static string[] SplitString(this string input, string seperator, StringSplitOptions splitOptions = StringSplitOptions.RemoveEmptyEntries, bool trimSpace = false)
{
string[] result = input.Split(new string[] { seperator }, splitOptions);
if (trimSpace)
{
return result.Select(s => s.Trim()).ToArray();
}
return result;
}
///
/// Splits the by comma or semi colon (,;).
///
/// The input.
/// The split options.
/// if set to true [trim space].
/// System.String[].
public static string[] SplitByCommaOrSemiColon(this string input, StringSplitOptions splitOptions = StringSplitOptions.RemoveEmptyEntries, bool trimSpace = false)
{
string[] result = input.Split( new char[] { ',', ';' }, splitOptions);
if (trimSpace)
{
return result.Select(s => s.Trim()).ToArray();
}
return result;
}
///
/// Splits the comma string.
///
/// The input.
/// The split options.
/// if set to true [trim space].
///
public static string[] SplitCommaString(this string input, StringSplitOptions splitOptions = StringSplitOptions.RemoveEmptyEntries, bool trimSpace = false)
{
string[] result = input.Split(new char[] { ',' }, splitOptions);
if (trimSpace)
{
return result.Select(s => s.Trim()).ToArray();
}
return result;
}
///
/// Splits the semi colon string.
///
/// The input.
/// The split options.
/// if set to true [trim space].
///
public static string[] SplitSemiColonString(this string input, StringSplitOptions splitOptions = StringSplitOptions.RemoveEmptyEntries, bool trimSpace = false)
{
string[] result = input.Split(new char[] { ';' }, splitOptions);
if (trimSpace)
{
return result.Select(s => s.Trim()).ToArray();
}
return result;
}
///
/// A case insenstive replace function.
///
/// The string to examine.
/// The value to replace.
/// The new value to be inserted
/// A string
public static string CaseInsenstiveReplace(this string value, string newValue, string oldValue)
{
Regex regEx = new Regex(oldValue, RegexOptions.IgnoreCase | RegexOptions.Multiline);
return regEx.Replace(value, newValue);
}
///
/// Removes the new line (\n) and carriage return (\r) symbols.
///
/// The string to search.
/// If true, adds a space (" ") for each newline and carriage
/// return found.
/// A string
public static string RemoveNewLines(this string value, bool addSpace = false)
{
string replace = string.Empty;
if (addSpace)
replace = " ";
string pattern = @"[\r|\n]";
Regex regEx = new Regex(pattern, RegexOptions.IgnoreCase | RegexOptions.Multiline);
return regEx.Replace(value, replace);
}
///
/// Reverse a string.
///
/// The string to reverse
/// A string
public static string Reverse(this string value)
{
if (value.Length <= 1)
return value;
char[] c = value.ToCharArray();
StringBuilder sb = new StringBuilder(c.Length);
for (int i = c.Length - 1; i > -1; i--)
sb.Append(c[i]);
return sb.ToString();
}
///
/// Converts a string to sentence case.
///
/// The string to convert.
/// A string
public static string SentenceCase(this string value)
{
if (value.Length < 1)
return value;
// start by converting entire string to lower case
var lowerCase = value.ToLower();
// matches the first sentence of a string, as well as subsequent sentences
var r = new Regex(@"(^[a-z])|\.\s+(.)", RegexOptions.ExplicitCapture);
// MatchEvaluator delegate defines replacement of setence starts to uppercase
return r.Replace(lowerCase, s => s.Value.ToUpper());
}
///
/// Converts a string to title case.
///
/// The string to convert.
/// A string.
public static string TitleCase(this string value)
{
if (value.Length < 1)
return value;
// start by converting entire string to lower case
var lowerCase = value.ToLower();
// matches the first sentence of a string, as well as subsequent sentences
var r = new Regex(@"\b(\w)", RegexOptions.ExplicitCapture);
// MatchEvaluator delegate defines replacement of setence starts to uppercase
return r.Replace(lowerCase, s => s.Value.ToUpper());
}
///
/// Determines whether the specified input is match.
///
/// The input.
/// The pattern (regular expression).
/// if set to true [ignore case].
///
/// true if the specified input is match; otherwise, false.
///
public static bool IsMatch(this string input, string pattern, bool ignoreCase = false)
{
return Regex.IsMatch(input, pattern, RegexOptions.IgnoreCase);
}
///
/// string like operator.
///
/// The input.
/// The pattern.
/// if set to true [ignore case].
///
public static bool StringLike(this string input, string pattern, bool ignoreCase = false)
{
return SQLLike(input, pattern.Replace("?", "_").Replace("*", "%"), ignoreCase);
}
///
/// SQL like operator.
///
/// The input.
/// The pattern.
/// if set to true [ignore case].
///
public static bool SQLLike(this string input, string pattern, bool ignoreCase)
{
/* Turn "off" all regular expression related syntax in
* the pattern string. */
pattern = Regex.Escape(pattern);
/* Replace the LIKE wildcard metacharacters with the
* equivalent regular expression metacharacters. */
pattern = pattern.Replace("_", ".").Replace("%", ".*");
/* The previous call to Regex.Escape actually turned off
* too many metacharacters, i.e. those which are recognized by
* both the regular expression engine and the LIKE
* statement ([...] and [^...]). Those metacharacters have
* to be manually unescaped here. */
pattern = pattern.Replace(@"\[", "[").Replace(@"\]", "]").Replace(@"\^", "^");
if (ignoreCase)
{
return Regex.IsMatch(input, pattern, RegexOptions.IgnoreCase);
}
else
{
return Regex.IsMatch(input, pattern);
}
}
///
/// SQLs the like pattern.
///
/// The input.
/// The pattern.
///
public static bool SQLLike(this string input, string pattern)
{
bool isMatch = true,
isWildCardOn = false,
isCharWildCardOn = false,
isCharSetOn = false,
isNotCharSetOn = false,
endOfPattern = false;
int lastWildCard = -1;
int patternIndex = 0;
List set = new List();
char p = '\0';
for (int i = 0; i < input.Length; i++)
{
char c = input[i];
endOfPattern = (patternIndex >= pattern.Length);
if (!endOfPattern)
{
p = pattern[patternIndex];
if (!isWildCardOn && p == '%')
{
lastWildCard = patternIndex;
isWildCardOn = true;
while (patternIndex < pattern.Length &&
pattern[patternIndex] == '%')
{
patternIndex++;
}
if (patternIndex >= pattern.Length) p = '\0';
else p = pattern[patternIndex];
}
else if (p == '_')
{
isCharWildCardOn = true;
patternIndex++;
}
else if (p == '[')
{
if (pattern[++patternIndex] == '^')
{
isNotCharSetOn = true;
patternIndex++;
}
else isCharSetOn = true;
set.Clear();
if (pattern[patternIndex + 1] == '-' && pattern[patternIndex + 3] == ']')
{
char start = char.ToUpper(pattern[patternIndex]);
patternIndex += 2;
char end = char.ToUpper(pattern[patternIndex]);
if (start <= end)
{
for (char ci = start; ci <= end; ci++)
{
set.Add(ci);
}
}
patternIndex++;
}
while (patternIndex < pattern.Length &&
pattern[patternIndex] != ']')
{
set.Add(pattern[patternIndex]);
patternIndex++;
}
patternIndex++;
}
}
if (isWildCardOn)
{
if (char.ToUpper(c) == char.ToUpper(p))
{
isWildCardOn = false;
patternIndex++;
}
}
else if (isCharWildCardOn)
{
isCharWildCardOn = false;
}
else if (isCharSetOn || isNotCharSetOn)
{
bool charMatch = (set.Contains(char.ToUpper(c)));
if ((isNotCharSetOn && charMatch) || (isCharSetOn && !charMatch))
{
if (lastWildCard >= 0) patternIndex = lastWildCard;
else
{
isMatch = false;
break;
}
}
isNotCharSetOn = isCharSetOn = false;
}
else
{
if (char.ToUpper(c) == char.ToUpper(p))
{
patternIndex++;
}
else
{
if (lastWildCard >= 0) patternIndex = lastWildCard;
else
{
isMatch = false;
break;
}
}
}
}
endOfPattern = (patternIndex >= pattern.Length);
if (isMatch && !endOfPattern)
{
bool isOnlyWildCards = true;
for (int i = patternIndex; i < pattern.Length; i++)
{
if (pattern[i] != '%')
{
isOnlyWildCards = false;
break;
}
}
if (isOnlyWildCards) endOfPattern = true;
}
return isMatch && endOfPattern;
}
}
}