StringPatternComparer.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. using System;
  2. using System.Collections.Generic;
  3. namespace Quadarax.Foundation.Core.Value
  4. {
  5. public class StringPatternComparer:IEqualityComparer<string>
  6. {
  7. #region *** Constants ***
  8. public const char CS_DEFAULT_EXCLUSION = '/';
  9. public const char CS_DEFAULT_ANYCHARS = '*';
  10. public const char CS_DEFAULT_ALPHACHARS = '?';
  11. public const char CS_DEFAULT_NUMCHARS = '#';
  12. public const char CS_DEFAULT_ALPHANUMCHARS = '%';
  13. public const char CS_DEFAULT_SPACECHARS = '_';
  14. #endregion
  15. #region *** Fields ***
  16. private readonly char _exclusionChar;
  17. private readonly char _anyChars;
  18. private readonly char _alphaChars;
  19. private readonly char _numChars;
  20. private readonly char _spaceChars;
  21. private readonly char _alphanumChars;
  22. #endregion
  23. #region *** Constructors ***
  24. public StringPatternComparer(char exclusionChar = CS_DEFAULT_EXCLUSION, char anyChars = CS_DEFAULT_ANYCHARS,
  25. char alphaChars = CS_DEFAULT_ALPHACHARS, char numChars = CS_DEFAULT_NUMCHARS,
  26. char alphanumChars = CS_DEFAULT_ALPHANUMCHARS, char spaceChars = CS_DEFAULT_SPACECHARS)
  27. {
  28. _exclusionChar = exclusionChar;
  29. _anyChars = anyChars;
  30. _alphaChars = alphaChars;
  31. _alphanumChars = alphanumChars;
  32. _numChars = numChars;
  33. _spaceChars = spaceChars;
  34. }
  35. #endregion
  36. #region *** Public Operations ***
  37. /// <summary>
  38. /// Equals method for string pattern comparison. Patterns are:
  39. /// Exclusion char: /
  40. /// Any chars: * (0 - n)
  41. /// Any Alpha chars: ? (0 - n)
  42. /// Any numeric chars: # (0 - n)
  43. /// Any alphanumeric chars: % (0 - n)
  44. /// Any space chars: _ (0 - n)
  45. /// </summary>
  46. /// <param name="x">First string represents value to compare.</param>
  47. /// <param name="y">Second string represents search pattern.</param>
  48. /// <returns></returns>
  49. public bool Equals(string? x, string? y)
  50. {
  51. if (string.IsNullOrEmpty(x) && string.IsNullOrEmpty(y)) return true;
  52. if (string.IsNullOrEmpty(x) || string.IsNullOrEmpty(y)) return false;
  53. var curIndex = 0;
  54. var isExcluded = false;
  55. for (var i = 0; i < y.Length; i++)
  56. {
  57. if (y[i] == _exclusionChar)
  58. {
  59. isExcluded = true;
  60. continue;
  61. }
  62. curIndex = IndexOfPattern(x,curIndex, y[i], isExcluded);
  63. if (isExcluded)
  64. isExcluded = false;
  65. if (curIndex == -2 || (curIndex == -1 && i == y.Length - 1))
  66. return false;
  67. }
  68. return y.Length > 0;
  69. }
  70. public int GetHashCode(string obj)
  71. {
  72. return obj.GetHashCode(StringComparison.InvariantCulture);
  73. }
  74. #endregion
  75. #region *** Private Operations ***
  76. private int IndexOfPattern(string source, int startIndex, char patternChar, bool isExcluded)
  77. {
  78. if (startIndex >= source.Length)
  79. return -1;
  80. if (patternChar == _exclusionChar || patternChar == _anyChars)
  81. return startIndex;
  82. if (!(patternChar == _alphaChars || patternChar == _numChars || patternChar == _alphanumChars ||
  83. patternChar == _spaceChars) || isExcluded)
  84. return source.IndexOf(patternChar, startIndex);
  85. for (var i = startIndex; i < source.Length; i++)
  86. {
  87. if ((patternChar == _alphaChars && char.IsLetter(source[i]))
  88. || (patternChar == _numChars && char.IsNumber(source[i]))
  89. || (patternChar == _alphanumChars && char.IsLetterOrDigit(source[i]))
  90. || (patternChar == _spaceChars && char.IsWhiteSpace(source[i]))
  91. )
  92. return i;
  93. }
  94. return -2;
  95. }
  96. #endregion
  97. }
  98. }