GMatchFunction.cs 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. using System.Text.RegularExpressions;
  2. using Lua.Internal;
  3. namespace Lua.Standard.Text;
  4. public sealed class GMatchFunction : LuaFunction
  5. {
  6. public override string Name => "gmatch";
  7. public static readonly GMatchFunction Instance = new();
  8. protected override ValueTask<int> InvokeAsyncCore(LuaFunctionExecutionContext context, Memory<LuaValue> buffer, CancellationToken cancellationToken)
  9. {
  10. var s = context.GetArgument<string>(0);
  11. var pattern = context.GetArgument<string>(1);
  12. var regex = StringHelper.ToRegex(pattern);
  13. buffer.Span[0] = new Iterator(regex.Matches(s));
  14. return new(1);
  15. }
  16. class Iterator(MatchCollection matches) : LuaFunction
  17. {
  18. int i;
  19. protected override ValueTask<int> InvokeAsyncCore(LuaFunctionExecutionContext context, Memory<LuaValue> buffer, CancellationToken cancellationToken)
  20. {
  21. if (matches.Count > i)
  22. {
  23. var match = matches[i];
  24. var groups = match.Groups;
  25. i++;
  26. if (groups.Count == 1)
  27. {
  28. buffer.Span[0] = match.Value;
  29. }
  30. else
  31. {
  32. for (int j = 0; j < groups.Count; j++)
  33. {
  34. buffer.Span[j] = groups[j + 1].Value;
  35. }
  36. }
  37. return new(groups.Count);
  38. }
  39. else
  40. {
  41. buffer.Span[0] = LuaValue.Nil;
  42. return new(1);
  43. }
  44. }
  45. }
  46. }