【问题标题】:Idiomatic way to parse and navigate UTF-8 byte stream解析和导航 UTF-8 字节流的惯用方式
【发布时间】:2016-11-03 20:37:19
【问题描述】:

我正在使用 Rust 开发一个词法分析器/标记器,它需要将 UTF-8 输入文件(以 &[u8] 给出)解析为单独的 chars 以进行解析,但还必须跟踪文件中的字节位置。在稍后阶段——比如当需要在输入中报告错误时——我需要根据字节定位有问题的字符并回溯以找到其行上的相对位置。

将字节流解析为字符的惯用方法是什么(跟踪字节位置);标准库中是否有函数允许我计算后面有多少个尾随字节,或者一个字节是前导字节还是尾随字节,还是我必须根据 Unicode 标准自己实现这些?

例如:

// First to parse some input stream:
let input: &[u8] = "something";
for (chr, bytepos) in parse(input) {
    // ...
}

// Later to locate a character based on the byte position and
// use is_leading_byte() to step backwards and count the number
// of characters since the start of the line:
let chr: u8 = input[some_bytepos];
chr.is_leading_byte();
chr.is_trailing_byte();

【问题讨论】:

  • 听起来您要求char_indices 并将其存储到Vec (let everything: Vec<_> = input.char_indices().collect()) 中。
  • 如果你有一个 UTF-8 的&[u8],你应该把它变成一个&str
  • 你真的需要每个字符的确切字节位置吗?似乎您最好知道行首的字节位置,然后知道行内的 Unicode 字符位置。
  • @Fabian:把这个放在这里;万一你不知道。 char 代表一个 Unicode 代码点,可能需要多个代码点来组成一个字素(尤其是涉及变音符号时,但不仅如此)。

标签: unicode utf-8 rust


【解决方案1】:

看来char_indices 解决了我的两个问题:

let input: &str = "something";
for (offset, chr) in input.char_indices() {
    // ...
}

在稍后阶段,可以使用split_at 来查找字符并向后计算行中前面字符的数量:

let input: &str = "something";
let where: usize = 4;
let (left,_) = input.split_at(where);
for (offset, chr) in left.char_indices().rev() {
    if chr == '\n' {
        break;
    }
    // ...
}

Matthieu M. 指出了一个警告:迭代和计算 Unicode 代码点并不一定与人们本能地认为的单个脚本字母相对应;这是因为多个代码点可能构成一个字形。 An example can be found in the documentation of chars().

【讨论】:

    猜你喜欢
    • 2018-04-02
    • 1970-01-01
    • 2013-08-14
    • 2012-11-29
    • 2012-11-13
    • 2012-11-07
    • 1970-01-01
    • 1970-01-01
    • 2015-07-26
    相关资源
    最近更新 更多