如何取消转义,在Rust中多次转义的字符串?

hk8txs48  于 2023-06-06  发布在  其他
关注(0)|答案(2)|浏览(293)

我已经花了将近一个小时在这上面,所以这是一个真正的碰壁的案例。
由于我无法控制的原因,我使用的一个内部服务提供给我一个如下格式的JSON

let dirty_string = r#"\"{\\\"key1\\\":\\\"val1\\\",\\\"key2\\\":\\\"val2\\\"}\""#;

很明显这看起来不对。我计划使用serde_json来构造适当的结构体,但这不起作用。
我已经尝试了各种方法来消除多重逃逸。
我已经尝试了各种形式的使用替换
这一
let to_format = dirty_string.replace("\\\\", r#""#);
给出了这个
"\\\"{\\\"key1\\\":\\\"val1\\\",\\\"key2\\\":\\\"val2\\\"}\\\""基本上使事情变得更糟
这个let to_format = dirty_string.replace("\\", r#""#);给出了这个
"\"{\"key1\":\"val1\",\"key2\":\"val2\"}\""
看起来差不多了,但是不起作用,因为当我试图将它解析为结构体时失败了

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
struct Parsed {
    key1: String,
    key2: String
}

let to_struct: Parsed = serde_json::from_str(&to_format).unwrap();
dbg!(to_struct);

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error("invalid type: string \"{\", expected struct Parsed", line: 1, column: 3)', src/main.rs:440:62
stack backtrace:
   0: rust_begin_unwind

所以我真的很感激你的帮助。
我如何才能成功地删除这个讨厌的反斜杠,使它成为一个有效的json字符串,然后我可以解析到结构。

flvlnr44

flvlnr441#

您可以添加引号并将其放入serde_json的三次迭代中:

let dirty_string = r#"\"{\\\"key1\\\":\\\"val1\\\",\\\"key2\\\":\\\"val2\\\"}\""#;
let s: String = serde_json::from_str(&format!(r#""{}""#, dirty_string)).unwrap();
let s: String = serde_json::from_str(&s).unwrap();
let value: serde_json::Value = serde_json::from_str(&s).unwrap();
println!("{value:#?}");
omjgkv6w

omjgkv6w2#

您所拥有的是一个JSON字符串,它再次被编码为JSON,最后具有反斜杠转义的字符(有PHP的addslashes()的味道)。因此,您需要按顺序执行这些步骤:

  • 去掉一组反斜杠,这将产生一个新的字符串。
  • JSON-从新的String中解码另一个String。
  • 最后,JSON反序列化到结构中。

例如:

use std::error::Error;

use serde::Deserialize;

#[derive(Deserialize, Debug)]
struct Data {
    pub key1: String,
    pub key2: String,
}

fn stripslashes(s: &str) -> Option<String> {
    let mut n = String::new();

    let mut chars = s.chars();

    while let Some(c) = chars.next() {
        n.push(match c {
            '\\' => chars.next()?,
            c => c,
        });
    }

    Some(n)
}

fn main() -> Result<(), Box<dyn Error>> {
    let dirty_string = r#"\"{\\\"key1\\\":\\\"val1\\\",\\\"key2\\\":\\\"val2\\\"}\""#;

    let s = stripslashes(&dirty_string).expect("stripslashes failed");
    let s: String = serde_json::from_str(&s)?;

    let data: Data = serde_json::from_str(&s)?;

    println!("{:?}", data);

    Ok(())
}

该输出:

Data { key1: "val1", key2: "val2" }

相关问题