StringExtensions.cs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. using System;
  2. using System.Globalization;
  3. using System.Text;
  4. using System.Text.RegularExpressions;
  5. namespace Jellyfin.Extensions
  6. {
  7. /// <summary>
  8. /// Provides extensions methods for <see cref="string" />.
  9. /// </summary>
  10. public static class StringExtensions
  11. {
  12. // Matches non-conforming unicode chars
  13. // https://mnaoumov.wordpress.com/2014/06/14/stripping-invalid-characters-from-utf-16-strings/
  14. private static readonly Regex _nonConformingUnicode = new Regex("([\ud800-\udbff](?![\udc00-\udfff]))|((?<![\ud800-\udbff])[\udc00-\udfff])|(\ufffd)", RegexOptions.Compiled);
  15. /// <summary>
  16. /// Removes the diacritics character from the strings.
  17. /// </summary>
  18. /// <param name="text">The string to act on.</param>
  19. /// <returns>The string without diacritics character.</returns>
  20. public static string RemoveDiacritics(this string text)
  21. => Diacritics.Extensions.StringExtensions.RemoveDiacritics(
  22. _nonConformingUnicode.Replace(text, string.Empty));
  23. /// <summary>
  24. /// Checks whether or not the specified string has diacritics in it.
  25. /// </summary>
  26. /// <param name="text">The string to check.</param>
  27. /// <returns>True if the string has diacritics, false otherwise.</returns>
  28. public static bool HasDiacritics(this string text)
  29. => Diacritics.Extensions.StringExtensions.HasDiacritics(text)
  30. || _nonConformingUnicode.IsMatch(text);
  31. /// <summary>
  32. /// Counts the number of occurrences of [needle] in the string.
  33. /// </summary>
  34. /// <param name="value">The haystack to search in.</param>
  35. /// <param name="needle">The character to search for.</param>
  36. /// <returns>The number of occurrences of the [needle] character.</returns>
  37. public static int Count(this ReadOnlySpan<char> value, char needle)
  38. {
  39. var count = 0;
  40. var length = value.Length;
  41. for (var i = 0; i < length; i++)
  42. {
  43. if (value[i] == needle)
  44. {
  45. count++;
  46. }
  47. }
  48. return count;
  49. }
  50. /// <summary>
  51. /// Returns the part on the left of the <c>needle</c>.
  52. /// </summary>
  53. /// <param name="haystack">The string to seek.</param>
  54. /// <param name="needle">The needle to find.</param>
  55. /// <returns>The part left of the <paramref name="needle" />.</returns>
  56. public static ReadOnlySpan<char> LeftPart(this ReadOnlySpan<char> haystack, char needle)
  57. {
  58. var pos = haystack.IndexOf(needle);
  59. return pos == -1 ? haystack : haystack[..pos];
  60. }
  61. /// <summary>
  62. /// Returns the part on the right of the <c>needle</c>.
  63. /// </summary>
  64. /// <param name="haystack">The string to seek.</param>
  65. /// <param name="needle">The needle to find.</param>
  66. /// <returns>The part right of the <paramref name="needle" />.</returns>
  67. public static ReadOnlySpan<char> RightPart(this ReadOnlySpan<char> haystack, char needle)
  68. {
  69. var pos = haystack.LastIndexOf(needle);
  70. if (pos == -1)
  71. {
  72. return haystack;
  73. }
  74. if (pos == haystack.Length - 1)
  75. {
  76. return ReadOnlySpan<char>.Empty;
  77. }
  78. return haystack[(pos + 1)..];
  79. }
  80. }
  81. }