使用 ReadOnlySpan<char> 处理转义序列

Dealing with escape sequences with ReadOnlySpan<char>

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


我有一个命令行 string,其中参数前缀 - 和分隔符 </code> (space) 被转义 <em>(我知道我可以在这里引用它们但是为了这个问题让我们假设它不是一个选项)</em>:</p> <pre><code> var str = @"foo -bar \-baz\ qux".AsMemory();

标记器应该return以下标记:

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

案例 12 很简单,因为在这里我可以只使用 str.Slice(i, length) 但我如何才能创建 3rd 案例和 return单身ReadOnlySpan<char>Slice 方法不允许我指定多个 start/length 范围,这是 跳过 转义字符 \ 所必需的范围。

示例:

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

其中 (10,4) = "-bar"(15,3) = " qux"

使用 StringBuilder 您可以只跳过几个字符,然后 Append 跳过其他字符。我如何使用 ReadOnlySpan<char> 获得相同的结果?

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

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

看看: 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()

希望对您有所帮助