如何在 Ruby 中每 n 个字符之后有效地拆分一个很长(数百万个字符)的字符串



假设我有一个字符串

string = "hellohellohey"

我想每 2 个字符拆分一次,所以它看起来像这样

string = ["he","ll","oh","el","lo","he","y"]

我尝试使用 scan(/.{2}/) 方法,但如果数组项不能除以 2,则不起作用。

编辑:有必要通知您,2个字符的事情就是一个例子。我正在做一件大事,所以我每 800 万个字符就会拆分一次。因此,将其拆分为单个字符并使用each_slice在这里不起作用。它只是冻结了我的笔记本电脑。

在处理(非常(大的字符串时,将它们包装在StringIO中会很有用。它提供了对字符串的高效类似文件的访问。

例如,您可以通过StringIO#each读取每n个字符:

string = "hellohellohey"
string_io = StringIO.new(string)
string_io.each(5) do |substring|
  p substring
end

输出:

"hello"
"hello"
"hey"

点匹配除换行符以外的任何字符。您正在尝试匹配任何字符的 2 倍,如果字符串长度为奇数,则不会匹配最后一个字符。

您可以使用贪婪的量词{1,2},因此它首先尝试匹配 2 次。

.{1,2}

观看演示

如果只想匹配小写字符 a-z,也可以使用 [a-z] 而不是点。

您可以链接多个方法,如下所示:

string = 'hellohellohey'
string.chars.each_slice(2).map { |s| s.join }
# => ["he", "ll", "oh", "el", "lo", "he", "y"]

#chars 会将字符串转换为字符数组。

#each_slice 将数组拆分为所需数量的部分。

更新 - 无中间/临时阵列

根据评论,多亏了@Cary Swoveland,可以避免临时阵列,如下所示。

string.each_char.each_slice(2).map { |s| s.join }

#each_char 给出了每个字符的枚举器。

最新更新