【问题标题】:Splitting a UTF-8 string into chunks将 UTF-8 字符串拆分成块
【发布时间】:2021-09-08 08:21:30
【问题描述】:

我想将一个 UTF-8 字符串拆分成大小相等的块。我想出了一个可以做到这一点的解决方案。现在我想简化它,如果可能的话,删除第一个对方付费电话。有办法吗?

fn main() {
    let strings = "ĄĆĘŁŃÓŚĆŹŻ"
        .chars()
        .collect::<Vec<char>>()
        .chunks(3)
        .map(|chunk| chunk.iter().collect::<String>())
        .collect::<Vec<String>>();
    println!("{:?}", strings);
}

Playground link

【问题讨论】:

  • 似乎,为了获得块,你需要收集成向量。见这里:stackoverflow.com/questions/42134874/…
  • 与 unicode 字符串一样,您需要注意“相等大小的块”的确切含义。您可能需要考虑字素而不是字符 - 因为这将拆分组合字符和组合表情符号。
  • 以下是@MichaelAnderson 提出的问题的示例:playground

标签: string rust iterator


【解决方案1】:

您可以使用chunks() from Itertools

use itertools::Itertools; // 0.10.1

fn main() {
    let strings = "ĄĆĘŁŃÓŚĆŹŻ"
        .chars()
        .chunks(3)
        .into_iter()
        .map(|chunk| chunk.collect::<String>())
        .collect::<Vec<String>>();
    println!("{:?}", strings);
}

【讨论】:

    【解决方案2】:

    这不需要 Itertools 作为依赖项,也不需要分配,因为它会迭代原始字符串的切片:

    fn chunks(s: &str, length: usize) -> impl Iterator<Item=&str> {
        assert!(length > 0);
        let mut indices = s.char_indices().map(|(idx, _)| idx).peekable();
        
        std::iter::from_fn(move || {
            let start_idx = match indices.next() {
                Some(idx) => idx,
                None => return None,
            };
            for _ in 0..length - 1 {
                indices.next();
            }
            let end_idx = match indices.peek() {
                Some(idx) => *idx,
                None => s.bytes().len(),
            };
            Some(&s[start_idx..end_idx])
        })
    }
    
    
    fn main() {
        let strings = chunks("ĄĆĘŁŃÓŚĆŹŻ", 3).collect::<Vec<&str>>();
        println!("{:?}", strings);
    }
    

    【讨论】:

      【解决方案3】:

      考虑到字素的问题,我最终得到了以下解决方案。

      我使用了 unicode-segmentation 板条箱。

      use unicode_segmentation::UnicodeSegmentation;                                                                                                                            
      
      fn main() {
          let strings = "ĄĆĘŁŃÓŚĆŹŻèèèèè"
              .graphemes(true)                                                                                                                                          
              .collect::<Vec<&str>>()                                                                                                                                   
              .chunks(length)                                                                                                                                           
              .map(|chunk| chunk.concat())                                                                                                                              
              .collect::<Vec<String>>();
          println!("{:?}", strings);
      }
      

      我希望仍然可以进行一些简化。

      【讨论】:

        猜你喜欢
        • 2014-03-06
        • 2015-07-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多