1

拥有一个字符串然后为此字符串调用子字符串更快,其中第一个子字符串将是初始字符串,并且每个新子字符串从初始子字符串中直到其结尾的一小部分?或者使用 StringBuilder 并从一开始就越来越多地切断,然后总是从收缩的字符串中使用 ToString?

链接描述了 StringBuilder ToString 方法仅在新线程访问 StringBuilder 或返回的 String 远小于当前分配的空间时才分配新空间。这听起来比使用 Substring 更快。我可以在.Net Framework 3.5的实现中看到这个逻辑。在 4.0 版中,可以立即调用 FastAllocateString(或多或少类似于 String Substring)。是不是和以前的框架版本一样的逻辑,只是现在隐藏了?

为什么我需要它:

编辑:更新解释:我有一个字符串和一组用户给定的正则表达式和上下文。上下文告诉我当前哪些正则表达式会很有趣,可以尝试与字符串的开头匹配。成功匹配后,字符串的开始现在位于最后一次匹配结束的位置之后。现在可能有不同的背景。另外我想知道上次哪个正则表达式与开始匹配。由于这是多次完成,因此性能应该尽可能好。

为了避免搜索整个(剩余的)字符串,我会使用起始锚(^),因此可以尽快中止搜索(在知道开始不匹配之后)。如果我这样做,我会遇到问题,即我不能将 Match 方法的起始索引参数与 0 以外的任何值一起使用。否则,由于锚点,将永远不会有匹配。

所以我想我现在有两种可能:

1)始终在输入字符串上使用 Substring 方法并为当前位置保留和索引。

2)使用 StringBuilder 并在匹配成功时始终删除输入的开头。然后调用 ToString 方法来查看新的开始是否与下一个 Regex 匹配。

上述一种或两种方法的性能是否可以接受,还是有另一种更快的方法?

Edit2:关于 StringBuilder 和 String:如此处所述 StringBuilder 的实现现在立即分配空间,而以前这被延迟到 StringBuilder 字符串被更改(这一直是我的要求的情况)。所以我猜 Substring 和 ToString 与 Kendall Frey 的纯正则表达式解决方案相比都非常慢。

4

2 回答 2

3

你不需要这样做。\G.NET 正则表达式引擎包含一项功能,可让您使用锚点匹配上一个匹配项之后的字符串。

正则表达式示例:

\Gcat

示例字符串:

catcatcatdogcat

火柴:

(cat)(cat)(cat)dogcat

编辑:我认为正则表达式不会让您记住\G多个正则表达式之间的锚点位置。相反,您可以使用Regex.Match(string, int)重载在某个点开始您的字符串,并使用\G锚点来匹配起始位置。

于 2012-07-25T18:12:21.190 回答
0

许多字符串操作方法都有带有开始/结束或开始/长度对的版本。

Regex.Match可用于匹配子字符串,这可能比在部分中切割字符串或插入标记字符更快。

public Match Match(string input, int beginning, int length)

注意:与任何性能问题一样,您需要尝试变体并衡量自己数据。

于 2012-07-25T18:06:41.293 回答