StringExtensions.cs 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. #pragma warning disable CS1591
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Globalization;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Text.RegularExpressions;
  8. namespace MediaBrowser.Controller.Extensions
  9. {
  10. /// <summary>
  11. /// Class BaseExtensions.
  12. /// </summary>
  13. public static class StringExtensions
  14. {
  15. public static string RemoveDiacritics(this string text)
  16. {
  17. var chars = Normalize(text, NormalizationForm.FormD)
  18. .Where(ch => CharUnicodeInfo.GetUnicodeCategory(ch) != UnicodeCategory.NonSpacingMark);
  19. return Normalize(string.Concat(chars), NormalizationForm.FormC);
  20. }
  21. /// <summary>
  22. /// Counts the number of occurrences of [needle] in the string.
  23. /// </summary>
  24. /// <param name="value">The haystack to search in.</param>
  25. /// <param name="needle">The character to search for.</param>
  26. /// <returns>The number of occurrences of the [needle] character.</returns>
  27. public static int CountOccurrences(this ReadOnlySpan<char> value, char needle)
  28. {
  29. var count = 0;
  30. var length = value.Length;
  31. for (var i = 0; i < length; i++)
  32. {
  33. if (value[i] == needle)
  34. {
  35. count++;
  36. }
  37. }
  38. return count;
  39. }
  40. private static string Normalize(string text, NormalizationForm form, bool stripStringOnFailure = true)
  41. {
  42. if (stripStringOnFailure)
  43. {
  44. try
  45. {
  46. return text.Normalize(form);
  47. }
  48. catch (ArgumentException)
  49. {
  50. // will throw if input contains invalid unicode chars
  51. // https://mnaoumov.wordpress.com/2014/06/14/stripping-invalid-characters-from-utf-16-strings/
  52. text = Regex.Replace(text, "([\ud800-\udbff](?![\udc00-\udfff]))|((?<![\ud800-\udbff])[\udc00-\udfff])", string.Empty);
  53. return Normalize(text, form, false);
  54. }
  55. }
  56. try
  57. {
  58. return text.Normalize(form);
  59. }
  60. catch (ArgumentException)
  61. {
  62. // if it still fails, return the original text
  63. return text;
  64. }
  65. }
  66. }
  67. }