Regex 如何在固定时间内替换字符串中的单个字符,并且不使用额外的空间?

Regex 如何在固定时间内替换字符串中的单个字符,并且不使用额外的空间?,regex,string,rust,Regex,String,Rust,这不是确切的用例,但基本上是我正在尝试做的: let mut username = "John_Smith"; println!("original username: {}",username); username.set_char_at(4,'.'); // <------------- The part I don't know how to do println!("new username: {}",username); 让mut username=“John_Smith”;

这不是确切的用例,但基本上是我正在尝试做的:

let mut username = "John_Smith";
println!("original username: {}",username);
username.set_char_at(4,'.'); // <------------- The part I don't know how to do
println!("new username: {}",username);
让mut username=“John_Smith”;
普林顿!(“原始用户名:{}”,用户名);

username.set_char_在(4,'。);// 一般来说?对于任何一对字符?这是不可能的


数组不是数组。在某些有限的上下文中,它可以实现为数组

Rust支持Unicode,这带来了一些挑战:

  • Unicode代码点可能是介于0和224之间的整数
  • 一个图形可以由多个Unicode代码点组成
为了表示这一点,Rust字符串(目前)是UTF-8字节序列:

  • 单个Unicode代码点可能由1到4个字节表示
  • 一个图形可能由1个或多个字节表示(无上限)
因此,“替换角色i”的概念本身就带来了一些挑战:

  • 字符
    i
    的位置在索引
    i
    和字符串末尾之间,需要从开头读取字符串才能知道确切的位置,即O(N)
  • 将第i个字符替换为另一个字符需要两个字符占用完全相同的字节数
一般来说?这是不可能的


在字节索引已知且字节编码在长度上已知的特定情况下,可以通过直接修改字节序列返回值来实现,因为您可能会无意中损坏字符串(请记住,此字节序列必须是UTF-8序列).

一般来说?对于任何一对字符?这是不可能的


数组不是数组。在某些有限的上下文中,它可以实现为数组

Rust支持Unicode,这带来了一些挑战:

  • Unicode代码点可能是介于0和224之间的整数
  • 一个图形可以由多个Unicode代码点组成
为了表示这一点,Rust字符串(目前)是UTF-8字节序列:

  • 单个Unicode代码点可能由1到4个字节表示
  • 一个图形可能由1个或多个字节表示(无上限)
因此,“替换角色i”的概念本身就带来了一些挑战:

  • 字符
    i
    的位置在索引
    i
    和字符串末尾之间,需要从开头读取字符串才能知道确切的位置,即O(N)
  • 将第i个字符替换为另一个字符需要两个字符占用完全相同的字节数
一般来说?这是不可能的


在字节索引已知且字节编码在长度上已知的特定情况下,可以通过直接修改字节序列返回值来实现,因为您可能会无意中损坏字符串(请记住,此字节序列必须是UTF-8序列).

如果只想处理ASCII,则有单独的类型:

use std::ascii::{AsciiCast, OwnedAsciiCast};

fn main() {
    let mut ascii = "ascii string".to_string().into_ascii();
    *ascii.get_mut(6) = 'S'.to_ascii();
    println!("result = {}", ascii);
}
有一些缺失的片段(比如
&str
的ascii
),但它可以满足您的需要。
如果输入字符串无效,
ascii
,则当前将
转换为ascii
的实现将失败。有
to_ascii_opt
(可能失败的方法的旧命名),但将来可能会重命名为
to_ascii
(并删除或重命名失败的方法)。

如果您只想处理ascii,则有单独的类型:

use std::ascii::{AsciiCast, OwnedAsciiCast};

fn main() {
    let mut ascii = "ascii string".to_string().into_ascii();
    *ascii.get_mut(6) = 'S'.to_ascii();
    println!("result = {}", ascii);
}
有一些缺失的片段(比如
&str
的ascii
),但它可以满足您的需要。
如果输入字符串无效,
ascii
,则当前将
转换为ascii
的实现将失败。有
to_ascii_opt
(可能失败的方法的旧命名),但将来可能会重命名为
to_ascii
(并删除或重命名失败的方法)。

从Rust 1.27开始,您现在可以使用:

()

replace\u range
将无法使用
&mut str
。如果范围的大小和替换字符串的大小不相同,则必须能够调整基础
字符串的大小,因此需要
和mut字符串的大小。但在您询问的情况下(将一个单字节字符替换为另一个单字节字符),其内存使用和时间复杂度都是O(1)


Vec
上也有类似的方法。它们之间的主要区别在于,
splice
返回一个迭代器,该迭代器生成删除的项。

从Rust 1.27开始,您现在可以使用:

()

replace\u range
不适用于
和mut str
。如果范围的大小和替换字符串的大小不相同,则必须能够调整基础
字符串的大小,因此需要
和mut字符串的大小。但在您询问的情况下(将一个单字节字符替换为另一个单字节字符),其内存使用和时间复杂度都是O(1)


Vec
上也有类似的方法。它们之间的主要区别在于,
splice
返回一个迭代器,该迭代器生成删除的项。

您可以在《启发》中找到答案。最值得注意的是,断言整个东西都是ASCII码是您合理地做到这一点的唯一方法。@ChrisMorgan--我找不到任何不需要在字符串上循环的答案。字符串在某个点上只是一个数组。我觉得应该有一个固定的时间来回答这个问题,不是吗?我想提请你们注意的是它的整个编码方面。(同样,如果你把一个字符串转换成ASCII,你就得到了
Vec
,因此常规的
Vec
方法是有效的。)但是,认真地说,重新考虑一下你是否应该这样做;通常答案是否定的,