You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何按换行符(\n或\r\n)分割非UTF-8编码的u8字节数组

字节数组多格式换行分割方案

原代码仅能识别CRLF(\r\n)换行,无法处理单独LF(\n)的情况,以下是兼容两种换行格式的实现:

use bytes::Bytes;
use std::iter::Peekable;

fn split_bytes_into_lines(bytes: &Bytes) -> Vec<Vec<u8>> {
    let mut iter = bytes.iter().peekable();
    let mut lines = Vec::new();

    while iter.peek().is_some() {
        let mut line = Vec::new();
        loop {
            match iter.peek() {
                Some(&&b'\n') => {
                    // 跳过LF,结束当前行
                    iter.next();
                    break;
                }
                Some(&&b'\r') => {
                    // 检查后续是否为LF,是则同时跳过CR和LF
                    if iter.peek().map(|&&c| c == b'\n').unwrap_or(false) {
                        iter.next();
                        iter.next();
                    } else {
                        // 单独CR也视为换行,跳过并结束行
                        iter.next();
                    }
                    break;
                }
                Some(&byte) => {
                    line.push(*byte);
                    iter.next();
                }
                None => break,
            }
        }
        lines.push(line);
    }

    lines
}

// 测试示例
fn main() {
    let test_data = Bytes::from("第一行\r\n第二行\n第三行\r第四行");
    let lines = split_bytes_into_lines(&test_data);
    
    for line in lines {
        println!("行内容: {:?}", String::from_utf8_lossy(&line));
    }
}

核心逻辑说明

  • 放弃原代码的2字节chunk迭代,改用单字节遍历,确保能单独识别LF(\n)
  • 分三种场景处理换行:
    • 遇到\n直接跳过并结束当前行
    • 遇到\r时,检查下一个字节是否为\n,若是则同时跳过两者;否则仅跳过\r并结束行
    • 非换行字节直接加入当前行缓冲区
  • 兼容CRLF、LF两种标准换行格式,同时支持单独CR的情况(可根据需求调整该逻辑)

原代码问题分析

原代码通过chunks(2)按双字节拆分,无法匹配单独的LF(单个字节),导致这类换行符会被当作普通字节加入行内容,无法正确分割。

内容的提问来源于stack exchange,提问作者kfeen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 11:42:19