gpt4 book ai didi

split - 如何在回车符 (\r) 或 CRLF (\r\n) 行终止符上拆分流?

转载 作者:行者123 更新时间:2023-11-29 08:22:39 27 4
gpt4 key购买 nike

我正在尝试拆分一个奇怪的串行端口流,该流以回车符 \r 分隔行,有时还使用 \r\nBufReader 具有lines 功能,但它只在\n\r\n 处拆分。有一个 .read_until(...) 函数,但它只适用于单个终止符。

基于 standard library's implementation ,我已经开始 cobble together 一些位,但我还没有让它编译。我希望我正在以“Rust 方式”正确地做这件事。正则表达式对于字节流来说似乎太昂贵了。

示例输入:

Heading:\r\nLine 1\rLine 2\rLine 3\r\nEnd

当您在该输入上使用 lines() 时,您会得到三行,因为 \r 不被视为行终止符:

Heading:
Line 1\rLine 2\rLine 2\rLine 3
End

最佳答案

基于我之前在 github 上的回答满足您的需求:

use std::io::{BufRead, BufReader};
use std::str;

#[derive(Debug)]
pub struct MyLines<B> {
buffer: B,
}

#[derive(Debug)]
pub enum MyError {
Io(std::io::Error),
Utf8(std::str::Utf8Error),
}

impl<B> MyLines<B> {
pub fn new(buffer: B) -> Self {
Self { buffer }
}
}

impl<B: BufRead> Iterator for MyLines<B> {
type Item = Result<String, MyError>;

fn next(&mut self) -> Option<Self::Item> {
let (line, total) = {
let buffer = match self.buffer.fill_buf() {
Ok(buffer) => buffer,
Err(e) => return Some(Err(MyError::Io(e))),
};
if buffer.is_empty() {
return None;
}
let consumed = buffer
.iter()
.take_while(|c| **c != b'\n' && **c != b'\r')
.count();
let total = consumed
+ if consumed < buffer.len() {
// we found a delimiter
if consumed + 1 < buffer.len() // we look if we found two delimiter
&& buffer[consumed] == b'\r'
&& buffer[consumed + 1] == b'\n'
{
2
} else {
1
}
} else {
0
};
let line = match str::from_utf8(&buffer[..consumed]) {
Ok(line) => line.to_string(),
Err(e) => return Some(Err(MyError::Utf8(e))),
};
(line, total)
};
self.buffer.consume(total);

Some(Ok(line))
}
}

fn main() {
let f = BufReader::new("Heading:\r\nLine 1\rLine 2\rLine 3\r\nEnd".as_bytes());

for line in MyLines::new(f) {
println!("{:?}", line);
}
}

输出:

Ok("Heading:")
Ok("Line 1")
Ok("Line 2")
Ok("Line 3")
Ok("End")

关于split - 如何在回车符 (\r) 或 CRLF (\r\n) 行终止符上拆分流?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55144120/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com