using System; using System.Globalization; using System.Text; using System.Text.RegularExpressions; namespace Jellyfin.Extensions { /// /// Provides extensions methods for . /// public static class StringExtensions { // Matches non-conforming unicode chars // https://mnaoumov.wordpress.com/2014/06/14/stripping-invalid-characters-from-utf-16-strings/ private static readonly Regex _nonConformingUnicode = new Regex("([\ud800-\udbff](?![\udc00-\udfff]))|((? /// Removes the diacritics character from the strings. /// /// The string to act on. /// The string without diacritics character. public static string RemoveDiacritics(this string text) { string withDiactritics = _nonConformingUnicode .Replace(text, string.Empty) .Normalize(NormalizationForm.FormD); var withoutDiactritics = new StringBuilder(); foreach (char c in withDiactritics) { UnicodeCategory uc = CharUnicodeInfo.GetUnicodeCategory(c); if (uc != UnicodeCategory.NonSpacingMark) { withoutDiactritics.Append(c); } } return withoutDiactritics.ToString().Normalize(NormalizationForm.FormC); } /// /// Checks whether or not the specified string has diacritics in it. /// /// The string to check. /// True if the string has diacritics, false otherwise. public static bool HasDiacritics(this string text) { return !string.Equals(text, text.RemoveDiacritics(), StringComparison.Ordinal); } /// /// Counts the number of occurrences of [needle] in the string. /// /// The haystack to search in. /// The character to search for. /// The number of occurrences of the [needle] character. public static int Count(this ReadOnlySpan value, char needle) { var count = 0; var length = value.Length; for (var i = 0; i < length; i++) { if (value[i] == needle) { count++; } } return count; } /// /// Returns the part on the left of the needle. /// /// The string to seek. /// The needle to find. /// The part left of the . public static ReadOnlySpan LeftPart(this ReadOnlySpan haystack, char needle) { var pos = haystack.IndexOf(needle); return pos == -1 ? haystack : haystack[..pos]; } /// /// Returns the part on the right of the needle. /// /// The string to seek. /// The needle to find. /// The part right of the . public static ReadOnlySpan RightPart(this ReadOnlySpan haystack, char needle) { var pos = haystack.LastIndexOf(needle); if (pos == -1) { return haystack; } if (pos == haystack.Length - 1) { return ReadOnlySpan.Empty; } return haystack[(pos + 1)..]; } } }