如何在Rust中删除字符串的第一个和最后一个字符?

41

我想知道如何在Rust中删除字符串的第一个和最后一个字符。

例如:

输入:

"Hello World"

输出:

"ello Worl"


你目前尝试了什么? - Alex
2
我明白了,在尝试之后,我会发布一个答案。 - Henry
4个回答

49
你可以使用 .chars() 迭代器,并忽略第一个和最后一个字符:
fn rem_first_and_last(value: &str) -> &str {
    let mut chars = value.chars();
    chars.next();
    chars.next_back();
    chars.as_str()
}

对于零或一个字符的字符串,它将返回空字符串,并且它将正确处理多字节Unicode字符。 在playground上查看其运行情况。


2
这是我最喜欢的答案,因为它可以处理多字节字符和空字符串。 - Henry
3
像往常一样,在使用Unicode时,值得记住字符和字形簇之间的区别。例如,有些情况下,这可能会删除最后一个字形上的重音,或更改一个复合表情符号,而不是删除整个簇。因此,虽然这符合OP的要求,但实际上可能并不是他们想要的。(这更像是对OP的警告,而不是对这个答案的批评——正确处理字形簇是非常棘手和不容易的)。 - Michael Anderson
2
@MichaelAnderson 当然可以!我从不知道在处理Unicode时该深入到什么程度。对于更复杂的字形和表情符号,可能需要将.chars()替换为.graphemes(true),使用unicode分段包。 - kmdreko

22
我通过使用字符串切片来实现这个。
fn main() {
    let string: &str = "Hello World";
    let first_last_off: &str = &string[1..string.len() - 1];
    println!("{}", first_last_off);
}

我取出了字符串中直到倒数第二个字符的所有字符。


1
如果字符串为空会发生什么?程序会崩溃吗? - Asnim P Ansari
1
我可以添加一个 if 语句:if string.is_empty() { "" } - Henry
我认为这个 &string[1..]; 也可以工作。 - gberth
7
警告:此代码仅适用于 ASCII 字符,其中 1 个字符 = 1 个字节。如果您的字符串以由 2 个或更多字节表示的 UTF-8 字符开头/结尾,则该代码将会出现错误。 - at54321

22

......甚至平凡的解决方案
也适用于Unicode字符:

let mut s = "Hello World".to_string();
s.pop();      // remove last
if s.len() > 0 {
    s.remove(0);  // remove first
}

1
值得注意的是,remove 是一个O(n)操作。 - Abhijit Sarkar
@Sarkar 正确 - 但它不会导致内存分配。 - Kaplan

0

你也可以使用 split_at()。

let msg = "Hello, world!";
let msg = msg.split_at(msg.len() - 1);
let msg = msg.0.split_at(1);
println!("{}", msg.1);

ello, world

split_at() 返回以下内容:(&str, &str)


1
您可以绑定到元组以丢弃未使用的部分:let (msg, _) = msg.split_at(msg.len() - 1); let (_, msg) = msg.split_at(1),但由于这会对非ASCII字符产生panic,因此在大多数情况下,我更倾向于使用kmdreko的答案。 - trent
我用“Jeg æder blåbærsyltetøj!”(丹麦语中的“我正在吃蓝莓果酱!”)替换了“hello”,结果是“eg æder blåbærsyltetøj”。 - kometen
3
J!是ASCII字符。尝试使用Я ем черничное варенье블루 베리 잼 먹고 있어요,你就会明白我的意思。 - trent
我明白了。我以为你的意思是它在计算UTF-8字符时出现错误,这可能会导致崩溃。 - kometen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接