2

据说ReadOnlySpan<char>它非常适合解析,所以我尝试使用它,但遇到了一个我不知道如何处理的用例。


我有一个命令行string,其中参数前缀-和分隔符(空格)被转义(我知道我可以在这里引用它们,但为了这个问题,让我们假设它不是一个选项)

 var str = @"foo -bar \-baz\ qux".AsMemory();

标记器应返回以下标记:

  1. foo- 命令名称
  2. bar- 参数名称
  3. -baz qux- 参数值

案例1&2很简单,因为在这里我可以使用str.Slice(i, length),但是如何创建3rd案例并只返回一个ReadOnlySpan<char>?该Slice方法不允许我指定跳过转义字符start/length所需的多个范围。\

例子:

str.Slice((10, 4), (15, 3)); 

在哪里(10,4) = "-bar"(15,3) = " qux"

StringBuilder您可以Append稍后跳过几个字符和其他字符。我将如何获得相同的结果ReadOnlySpan<char>

4

2 回答 2

2

ASpan/ReadOnlySpan是一个连续的内存块。它不能包含多个范围。这种设计是性能所必需的。Span/ReadOnlySpan应该与数组大致一样快。数组速度很快,因为它们是连续的内存块,没有进一步的抽象。

如果不分配新字符串,我看不到这样做的方法。您可以使用Span/ReadOnlySpan所有连续的子字符串,但您的解析问题似乎不适合使用 span 来存储结果。

于 2018-07-15T09:55:14.350 回答
2

看看: https ://github.com/nemesissoft/Nemesis.TextParsers

更准确地说是: TokenSequence.cs

用法:

var tokens = "ABC|CD\|E".AsSpan().Tokenize('|', '\\', false); //no allocation. Result in 2 elements: "ABC", "CD\|E". 

通过以下方式消费:

var result = new List<string>();
foreach (var part in tokens)
     result.Add(part.ToString());

可以通过以下方式进行取消转义: ParsedSequence.cs

SpanParserHelper.UnescapeCharacter()

希望这可以帮助

于 2019-05-06T12:18:40.597 回答