【问题标题】:Iterate over lines in a string, including the newline characters遍历字符串中的行,包括换行符
【发布时间】:2016-11-07 00:05:31
【问题描述】:

我需要遍历字符串中的行,但将换行符保留在产生的字符串的末尾。

str.lines(),但它返回的字符串中的换行符被剪掉了:

let result: Vec<_> = "foo\nbar\n".lines().collect();
assert_eq!(result, vec!["foo", "bar"]);

这是我需要的:

assert_eq!(lines("foo\nbar\n"), vec!["foo\n", "bar\n"]);

更多测试用例:

assert!(lines("").is_empty());
assert_eq!(lines("f"), vec!["f"]);
assert_eq!(lines("foo"), vec!["foo"]);
assert_eq!(lines("foo\n"), vec!["foo\n"]);
assert_eq!(lines("foo\nbar"), vec!["foo\n", "bar"]);
assert_eq!(lines("foo\r\nbar"), vec!["foo\r\n", "bar"]);
assert_eq!(lines("foo\r\nbar\r\n"), vec!["foo\r\n", "bar\r\n"]);
assert_eq!(lines("\nfoo"), vec!["\n", "foo"]);
assert_eq!(lines("\n\n\n"), vec!["\n", "\n", "\n"]);

我有一个基本上在循环中调用find 的解决方案,但我想知道是否有更优雅的东西。

这类似于Split a string keeping the separators,但在这种情况下,字符作为单独的项目返回,但我想将它们保留为字符串的一部分:

["hello\n", "world\n"]; // This
["hello", "\n", "world", "\n"]; // Not this

【问题讨论】:

    标签: string rust


    【解决方案1】:

    我目前的解决方案是这样的:

    /// Iterator yielding every line in a string. The line includes newline character(s).
    pub struct LinesWithEndings<'a> {
        input: &'a str,
    }
    
    impl<'a> LinesWithEndings<'a> {
        pub fn from(input: &'a str) -> LinesWithEndings<'a> {
            LinesWithEndings {
                input: input,
            }
        }
    }
    
    impl<'a> Iterator for LinesWithEndings<'a> {
        type Item = &'a str;
    
        #[inline]
        fn next(&mut self) -> Option<&'a str> {
            if self.input.is_empty() {
                return None;
            }
            let split = self.input.find('\n').map(|i| i + 1).unwrap_or(self.input.len());
            let (line, rest) = self.input.split_at(split);
            self.input = rest;
            Some(line)
        }
    }
    

    【讨论】:

    • 如果您使用slice::split_at,则不需要start 参数:然后您可以在循环的每次迭代中更新self.input
    • 感谢@MatthieuM.,这简化了它!
    猜你喜欢
    • 2011-05-13
    • 2011-03-04
    • 2012-09-12
    • 2013-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多