如何按换行符(\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
相关产品推荐
相关产品推荐

