using System; using System.Collections.Generic; namespace Quadarax.Foundation.Core.Value { public class StringPatternComparer:IEqualityComparer { #region *** Constants *** public const char CS_DEFAULT_EXCLUSION = '/'; public const char CS_DEFAULT_ANYCHARS = '*'; public const char CS_DEFAULT_ALPHACHARS = '?'; public const char CS_DEFAULT_NUMCHARS = '#'; public const char CS_DEFAULT_ALPHANUMCHARS = '%'; public const char CS_DEFAULT_SPACECHARS = '_'; #endregion #region *** Fields *** private readonly char _exclusionChar; private readonly char _anyChars; private readonly char _alphaChars; private readonly char _numChars; private readonly char _spaceChars; private readonly char _alphanumChars; #endregion #region *** Constructors *** public StringPatternComparer(char exclusionChar = CS_DEFAULT_EXCLUSION, char anyChars = CS_DEFAULT_ANYCHARS, char alphaChars = CS_DEFAULT_ALPHACHARS, char numChars = CS_DEFAULT_NUMCHARS, char alphanumChars = CS_DEFAULT_ALPHANUMCHARS, char spaceChars = CS_DEFAULT_SPACECHARS) { _exclusionChar = exclusionChar; _anyChars = anyChars; _alphaChars = alphaChars; _alphanumChars = alphanumChars; _numChars = numChars; _spaceChars = spaceChars; } #endregion #region *** Public Operations *** /// /// Equals method for string pattern comparison. Patterns are: /// Exclusion char: / /// Any chars: * (0 - n) /// Any Alpha chars: ? (0 - n) /// Any numeric chars: # (0 - n) /// Any alphanumeric chars: % (0 - n) /// Any space chars: _ (0 - n) /// /// First string represents value to compare. /// Second string represents search pattern. /// public bool Equals(string? x, string? y) { if (string.IsNullOrEmpty(x) && string.IsNullOrEmpty(y)) return true; if (string.IsNullOrEmpty(x) || string.IsNullOrEmpty(y)) return false; var curIndex = 0; var isExcluded = false; for (var i = 0; i < y.Length; i++) { if (y[i] == _exclusionChar) { isExcluded = true; continue; } curIndex = IndexOfPattern(x,curIndex, y[i], isExcluded); if (isExcluded) isExcluded = false; if (curIndex == -2 || (curIndex == -1 && i == y.Length - 1)) return false; } return y.Length > 0; } public int GetHashCode(string obj) { return obj.GetHashCode(StringComparison.InvariantCulture); } #endregion #region *** Private Operations *** private int IndexOfPattern(string source, int startIndex, char patternChar, bool isExcluded) { if (startIndex >= source.Length) return -1; if (patternChar == _exclusionChar || patternChar == _anyChars) return startIndex; if (!(patternChar == _alphaChars || patternChar == _numChars || patternChar == _alphanumChars || patternChar == _spaceChars) || isExcluded) return source.IndexOf(patternChar, startIndex); for (var i = startIndex; i < source.Length; i++) { if ((patternChar == _alphaChars && char.IsLetter(source[i])) || (patternChar == _numChars && char.IsNumber(source[i])) || (patternChar == _alphanumChars && char.IsLetterOrDigit(source[i])) || (patternChar == _spaceChars && char.IsWhiteSpace(source[i])) ) return i; } return -2; } #endregion } }