一种简洁而安全的方法,用其他ASCII字符替换字符串中特定的ASCII字符。

3
我想编写一个函数,它接受一个可变字符串并检查第一个和最后一个字符是否为"字符。如果是,这两个字符应该用反引号字符`替换。我已经想出了以下解决方法:
fn replace_wrapping_char(s: &mut String) {
    if s.len() > 1 && s.starts_with('"') && s.ends_with('"') {
        unsafe {
            let v = s.as_mut_vec();
            v[0] = '`' as u8;
            *v.last_mut().unwrap() = '`' as u8;
        }
    }
}

这似乎可行(是的,'`'.is_ascii()返回true),但它使用了unsafe并且在我看来有点丑。

是否有一种安全而简洁的方法来实现我的目标呢?


https://dev59.com/44Tba4cB1Zd3GeqP7o_Z - Josh Lee
你知道整个字符串是否都是ASCII码,还是只保证第一个/最后一个字符可能是ASCII码? - Shepmaster
@Shepmaster 我对字符串的ASCII特性一无所知。如果第一个/最后一个字符是",那么它们是ASCII码(显然...),否则不能保证。 - Lukas Kalbertodt
1
我猜你想要的是如果AsciiExt有一个set_ascii_char_at(index, new_char),它返回一个Result<>而不是在无法工作时发生异常。但今天似乎没有类似的东西。 - Chris Emerson
1个回答

1
这是一个安全的、缩短版的函数,虽然它不太节省内存。它会创建一个副本并重新分配给定的字符串,因此在这里返回一个新字符串的纯函数原型可能更合适。它还依赖于双引号字符在UTF-8中为1字节大小的事实。
fn replace_wrapping_char(s: &mut String) {
    if s.len() > 1 && s.starts_with('"') && s.ends_with('"') {
        *s = format!("`{}`", &s[1 .. s.len()-1])
    }
}

游乐场


1
新手问题,但这不是复制整个字符串然后重新分配给s吗?有没有一种只通过改变第一个和最后一个字节就可以完成的方法? - Alec
@Alec 没错,这会复制并重新分配字符串,所以我承认这不是解决问题的最佳方案。尽管如此,我还是会把它放在这里,以防有人可以接受复制。 - E net4
@Alec 通过仅改变第一个和最后一个字节来实现 - 这就是 OP 的解决方案所做的,但它必须是不安全的,因为类型系统无法保证第一个/最后一个字节 ASCII 并且保持 ASCII。 - Shepmaster

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