C# 使用ReadOnlySpan

C# 使用ReadOnlySpan,c#,parsing,system.memory,C#,Parsing,System.memory,ReadOnlySpan据说非常适合解析,所以我尝试使用它,但遇到了一个我不知道如何处理的用例 我有一个命令行字符串,其中参数前缀和分隔符空间被转义。我知道我可以在这里引用它们,但出于这个问题,让我们假设它不是一个选项: 标记器应返回以下标记: foo-命令名 bar-参数名称 -baz-qux-参数值 案例1和案例2很简单,因为这里我可以只使用str.Slicei,length,但是如何创建第三个案例并只返回一个ReadOnlySpan?Slice方法不允许我指定多个起始/长度范围,这对于跳过

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

我有一个命令行字符串,其中参数前缀和分隔符空间被转义。我知道我可以在这里引用它们,但出于这个问题,让我们假设它不是一个选项:

标记器应返回以下标记:

foo-命令名 bar-参数名称 -baz-qux-参数值 案例1和案例2很简单,因为这里我可以只使用str.Slicei,length,但是如何创建第三个案例并只返回一个ReadOnlySpan?Slice方法不允许我指定多个起始/长度范围,这对于跳过转义字符\是必要的

例如:

式中,10,4=-bar和15,3=qux

使用StringBuilder,您可以跳过几个字符,稍后再附加其他字符。如何使用ReadOnlySpan获得相同的结果?

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

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

请查看:

更确切地说,在:

用法:

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());

希望这有帮助

切片方法不允许我指定多个起始/长度范围,我不太明白您在这里的意思。你能解释一下吗?另外,在这里使用span看起来就像是用大锤敲打苍蝇,当然,如果你想知道span和内存的分配非常棒,但这只是一个命令行参数,不管怎样,你似乎必须穿过跨度。@这里一般使用跨度就像是用大锤击打苍蝇-我知道-在这种情况下,这可能是真的,但系统。内存包是非常新的,你已经开始了,所以我选择了一个非常简单的用例来处理,所以让我们暂时忘记有其他方法;-我所说的多重开始/长度是指类似于这个str.10、4、15、3;其中10,4=-bar和15,3=qux。您写的是Span,但问题是关于ReadOnlySpan。对于ReadOnlySpan,您的答案是正确的。如果您确实想提到Span,还有另一个选项:就地修改缓冲区。@hvd就地写入是一个很好的观点,尽管就地修改字符串似乎很不安全。谁知道那会打破什么。他可以使用char[].@hvd@usr,所以我猜解析任何涉及转义序列html、json、csv的内容。。。使用系统内存是无法完成的,对吧?解析通常更容易或更有效。存储解析结果是另一回事。你说得对,转义序列使在这里使用Span变得不可能。酷!我来看看-这也可通过nuget获得:
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());
SpanParserHelper.UnescapeCharacter()