using System; using System.Collections.Generic; using System.Text; namespace WinWARP.Core.Helper; public static class FlagEmojiParser { private const int RegionalIndicatorStart = 0x1F1E6; // '🇦' private const int RegionalIndicatorEnd = 0x1F1FF; // '🇿' /// /// Parses a string and returns a list of ISO 3166-1 alpha-2 country codes found as emojis. /// public static List ExtractCountryCodes(string text, out List countryIndicators) { countryIndicators = []; var countryCodes = new List(); if (string.IsNullOrEmpty(text)) return countryCodes; var i = 0; int? firstLetterCode = null; while (i < text.Length) { // Read the 32-bit Unicode code point (handles emoji surrogate pairs) var codePoint = char.ConvertToUtf32(text, i); // Advance the index (surrogate pairs take 2 char slots in .NET strings) i += char.IsSurrogatePair(text, i) ? 2 : 1; // Check if the character is a Regional Indicator Symbol (A-Z flag component) if (codePoint >= RegionalIndicatorStart && codePoint <= RegionalIndicatorEnd) { var letterOffset = codePoint - RegionalIndicatorStart; // 0 for A, 1 for B... if (firstLetterCode == null) { // This is the first letter of a flag pair firstLetterCode = letterOffset; } else { // This is the second letter of a flag pair. Construct the ISO string. var c1 = (char)('A' + firstLetterCode.Value); var c2 = (char)('A' + letterOffset); countryCodes.Add($"{c1}{c2}"); countryIndicators.Add($"{char.ConvertFromUtf32(RegionalIndicatorStart + firstLetterCode.Value)}{char.ConvertFromUtf32(RegionalIndicatorStart + letterOffset)}"); // Reset to look for the next flag firstLetterCode = null; } } else { // If we hit any other character, break any broken/incomplete flag sequences firstLetterCode = null; } } return countryCodes; } public static List ExtractCountryCodes(string text) { return ExtractCountryCodes(text, out _); } }