regex - "decimal literal empty"在 Rust 中为正则表达式组合多个字符串时

标签 regex rust

我想解析一个字符串来创建一个浮点向量:

fn main() {
    let vector_string: &str = "{12.34, 13.}";
    let vec = parse_axis_values(vector_string);
    // --- expected output vec: Vec<f32> = vec![12.34, 13.]
}

use regex::Regex;

pub fn parse_axis_values(str_values: &str) -> Vec<f32> {
    let pattern_float = String::from(r"\s*(\d*.*\d*)\s*");
    let pattern_opening = String::from(r"\s*{{");
    let pattern_closing = String::from(r"}}\s*");
    let pattern =
        pattern_opening + "(" + &pattern_float + ",)*" + &pattern_float + &pattern_closing;
    let re = Regex::new(&pattern).unwrap();
    let mut vec_axis1: Vec<f32> = Vec::new();
    // --- snip : for loop for adding the elements to the vector ---

    vec_axis1
}

此代码可以编译,但在展开 Regex::new() 时会在运行时出现错误:

regex parse error:
    \s*{{(\s*(\d*.*\d*)\s*,)*\s*(\d*.*\d*)\s*}}\s*
        ^
error: decimal literal empty

根据其他帖子,当没有正确转义大括号 { 时可能会出现此错误,但我认为我正确地转义了括号。

这个正则表达式有什么问题?

最佳答案

你的代码有几个问题:

  1. Escaping a { in regex is done with \{ .

  2. 您的 . 匹配任何字符,但不包含您想要的内容。你必须逃离它。

  3. 您捕获的不仅仅是数字,这使得解析更加复杂。

  4. 您的正则表达式构建不必要冗长,您可以在没有它的情况下发表评论。

这是一个提议的改进版本:

use regex::Regex;

pub fn parse_axis_values(str_values: &str) -> Vec<f32> {
    let re = Regex::new(r"(?x)
        \s*\{\s*        # opening
        (\d*\.\d*)      # captured float
        \s*,\s*         # separator
        \d*\.\d*        # ignored float
        \s*\}\s*        # closing
    ").unwrap();
    let mut vec_axis1: Vec<f32> = Vec::new();
    if let Some(c) = re.captures(str_values) {
        if let Some(g) = c.get(1) {
            vec_axis1.push(g.as_str().parse().unwrap());
        }
    }
    vec_axis1
}

fn main() {
    let vector_string: &str = "{12.34, 13.}";
    let vec = parse_axis_values(vector_string);
    println!("v: {:?}", vec);
}

playground

如果多次调用此函数,您可能需要 avoid recompiling the regex at each call也。

I want to be able to match 0.123, .123, 123 or 123., the use of d+ would break these possibilities

看起来您想获取字符串中的所有 float 。这可以像这样简单地完成:

use regex::Regex;

pub fn parse_axis_values(str_values: &str) -> Vec<f32> {
    let re = Regex::new(r"\d*\.\d*").unwrap();
    let mut vec_axis1: Vec<f32> = Vec::new();
    for c in re.captures_iter(str_values) {
        vec_axis1.push(c[0].parse().unwrap());
    }
    vec_axis1
}

如果你想要两者:

  • 检查完整的字符串是否正确包裹在 {} 之间
  • 获取所有数字

那么你可以:

  • 合并两个正则表达式(第一个用于提取内部部分)
  • 使用基于 Serde 的解析器(此时我不会,但如果问题的复杂性增加,这会很有趣)

关于regex - "decimal literal empty"在 Rust 中为正则表达式组合多个字符串时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53948147/

相关文章:

r - 在 R 中使用 AND 和 OR bool 运算符检测字符串

php - 将 PHP Regex 转换为 Javascript(或者有什么区别?)

mongodb - Rust Actix Web 是否支持 MongoDB?

rust - 如何更改 Serde 的默认实现以返回一个空对象而不是 null?

rust - 为什么不能将结构分配给具有它实现的特征的绑定(bind)

Javascript 正则表达式字符排除

java - 字符串拆分,包括重音字符的单词

javascript - 拆分文件夹路径字符串

android - 在 x86_64 上使用 x86_64 NDK 工具链链接失败

rust - 我如何告诉编译器在不删除整个结构的情况下释放结构中的借用?