StringExtensions.cs 2.3 KB

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