FeedContent.cs 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. using System.Text.RegularExpressions;
  2. namespace Application.Features.Api.Feed.Shared;
  3. public static partial class FeedContent
  4. {
  5. [GeneratedRegex(@"<[^>]+>", RegexOptions.Compiled)]
  6. private static partial Regex HtmlTagRegex();
  7. [GeneratedRegex(@"\s+", RegexOptions.Compiled)]
  8. private static partial Regex WhitespaceRegex();
  9. public static string Excerpt(string? html, int maxLength)
  10. {
  11. if (string.IsNullOrWhiteSpace(html))
  12. {
  13. return string.Empty;
  14. }
  15. var stripped = HtmlTagRegex().Replace(html, " ");
  16. var normalized = WhitespaceRegex().Replace(stripped, " ").Trim();
  17. if (normalized.Length <= maxLength)
  18. {
  19. return normalized;
  20. }
  21. return string.Concat(normalized.AsSpan(0, maxLength), "…");
  22. }
  23. [GeneratedRegex(@"#([\p{L}\p{N}_가-힣]+)", RegexOptions.Compiled)]
  24. public static partial Regex HashtagRegex();
  25. [GeneratedRegex(@"@([A-Za-z0-9]{3,20})", RegexOptions.Compiled)]
  26. public static partial Regex MentionRegex();
  27. public static List<string> ExtractHashtags(string? text, int maxTags = 10)
  28. {
  29. if (string.IsNullOrWhiteSpace(text))
  30. {
  31. return [];
  32. }
  33. var seen = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
  34. var result = new List<string>();
  35. foreach (Match m in HashtagRegex().Matches(text))
  36. {
  37. var tag = m.Groups[1].Value;
  38. if (seen.Add(tag))
  39. {
  40. result.Add(tag);
  41. if (result.Count >= maxTags)
  42. {
  43. break;
  44. }
  45. }
  46. }
  47. return result;
  48. }
  49. public static List<string> ExtractMentions(string? text, int maxMentions = 20)
  50. {
  51. if (string.IsNullOrWhiteSpace(text))
  52. {
  53. return [];
  54. }
  55. var seen = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
  56. var result = new List<string>();
  57. foreach (Match m in MentionRegex().Matches(text))
  58. {
  59. var sid = m.Groups[1].Value;
  60. if (seen.Add(sid))
  61. {
  62. result.Add(sid);
  63. if (result.Count >= maxMentions)
  64. {
  65. break;
  66. }
  67. }
  68. }
  69. return result;
  70. }
  71. }