You can always write a parser:
(float? f, float? g) ParseTwoFloats(string input)
{
if (!input.StartsWith('#')) return (null, null);
var currentBlock = default(char?);
var currentStartIndex = default(int?);
var f = default(float?);
var g = default(float?);
for (var index = 1; index < input.Length; index++)
{
var token = input[index];
switch (token)
{
case 'F':
case 'G':
{
if (currentBlock.HasValue) UpdateWithNew(index);
currentBlock = token;
currentStartIndex = index;
break;
}
}
}
if (currentBlock.HasValue) UpdateWithNew(input.Length - 1);
void UpdateWithNew(int index)
{
var value = float.Parse(
input.AsSpan(currentStartIndex.Value + 1, index - currentStartIndex.Value - 1),
provider: CultureInfo.InvariantCulture);
switch (currentBlock.Value)
{
case 'F': f = value; break;
case 'G': g = value; break;
}
}
return (f, g);
}
This does no heap allocations and is pretty easy to extend based on your other needs (e.g. adding another thing to parse, things to skip, proper error handling etc.).
If you want something even simpler, you can always do something like this:
(float f, float g) ParseTwoFloats(string input)
{
return (FindByToken(input, 'F', 'G'), FindByToken(input, 'G', 'F'));
float FindByToken(string input, char startToken, char endToken) =>
input.IndexOf(startToken) is {} start
? Parse(input, start + 1, input.IndexOf(endToken, start))
: 0f;
float Parse(string input, int start, int end) =>
float.Parse(input.AsSpan(start, end == -1 ? input.Length - start : end - start),
provider: CultureInfo.InvariantCulture);
}
This is less flexible, and does involve two iterations through the string. The iteration can be faster than in the parser. As with the parser, there's no heap allocations.
You can probably do even better if you replace the string input with another ReadOnlySpan (assuming you're working on substrings of a larger string) - avoiding heap allocations can make a huge difference when parsing string data. If you can avoid creating millions of substrings, you can get a pretty nice improvement. But as always, measure first.