rust语言,将JSON中的所有值以字符串形式存储到sqlite数据库中(逐行注释)

主要功能实现:

  • 所有json中数字转为字符串,保持精度不变
  • 巨大值 直接存储为字符串:3355446515156151516158.55125184845684
  • 值为列表["egeggeg","gegeg",25.5] 存储为: ["egeggeg","gegeg","25.5"]
  • 值为字典{"name":"小小","age":26} 存储为: {"name":"小小","age":"26"}

代码

rust 复制代码
use regex::Regex;
use rusqlite::{Connection, Result, params};
use serde_json::Value;
use std::collections::HashMap;
use std::error::Error;

// 使用正则表达式将JSON中的数值类型转换为字符串类型
fn convert_numbers_to_strings_with_regex(json_str: &str) -> Result<String, Box<dyn Error>> {
    // 创建一个新的正则表达式,使用更简单的方法来匹配数值
    let mut result = json_str.to_string();

    // 首先处理对象中的数值:"key":数字
    // 我们使用更简单的模式,匹配键值对中的数值部分
    let re_obj_value = Regex::new(
        r#"([^"]+)"\s*:\s*(-?(?:\d+(?:\.\d*)?(?:[eE][+-]?\d+)?|\.\d+(?:[eE][+-]?\d+)?))"#,
    )?;
    result = re_obj_value.replace_all(&result, r#"$1":"$2""#).to_string();

    // 然后处理数组中的数值:[数字,...]
    // 使用数组边界和逗号作为上下文,避免匹配到字符串中的数字
    let re_arr_value = Regex::new(
        r#"([\[\s,])\s*(-?(?:\d+(?:\.\d*)?(?:[eE][+-]?\d+)?|\.\d+(?:[eE][+-]?\d+)?))\s*([\],])"#,
    )?;
    result = re_arr_value.replace_all(&result, r#"$1"$2"$3"#).to_string();

    Ok(result)
}

fn main() -> Result<(), Box<dyn Error>> {
    let original_json_str = r#"
        [
            {
                "name":"张三",
                "as_name":"阿三",
                "age":15.3200001,
                "hobby":["足球",3.25,"羽毛球"],
                "grade":{"语文":99999999999999999.999999999999999,"数学":96.44,"英语":"77.2511002"},
                "membe":true
            },
            {
            	"name":"李四",
                "age":17,
                "hobby":[3.2,"篮球",10.2555],
                "grade":{"语文":99999999999999999999999999999999,"数学":0.000000000000222,"英语":94.67},
                "membe":false
            },
            {
            	"name":"王五",
                "age":"5.25",
                "hobby":[7.7,"3.222"],
                "grade":{"语文":"999999999999999999999999999","数学":"0.000000000000222","英语":0},
                "membe":false
            }
        ]
    "#;

    // 使用正则表达式将JSON中的数值转换为字符串
    let converted_json_str = convert_numbers_to_strings_with_regex(original_json_str)?;

    // 连接到 SQLite 数据库
    let conn = Connection::open("tt.db")?;
    // 创建表
    create_db(&conn)?;
    // 解析转换后的JSON字符串
    let json_value: Value = serde_json::from_str(&converted_json_str)?;
    parse_json_and_store_in_db(&conn, &json_value)?;
    Ok(())
}

// 创建数据库表
fn create_db(conn: &Connection) -> Result<()> {
    conn.execute(
        "CREATE TABLE IF NOT EXISTS test_table (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            name TEXT NOT NULL,
            as_name TEXT,
            age TEXT,
            hobby TEXT,
            grade TEXT,
            membe TEXT
        )",
        [],
    )?;
    Ok(())
}

// 解析 json 并存入数据库
fn parse_json_and_store_in_db(conn: &Connection, json_str: &Value) -> Result<(), Box<dyn Error>> {
    if let Value::Array(arr) = json_str {                   // 获取json中的列表
        for item in arr {                                        // 循环遍历列表
            if let Value::Object(obj) = item {   // 获取json中的字典类型
                let mut name = String::new();                // 不为空的字段
                let mut as_name = None;                      // 可以为空的字段
                let mut age = None;
                let mut hobby = None;
                let mut grade = None;
                let mut membe = None;
                for (key, value) in obj {            // 循环遍历字典中的键值对
                    match key.as_str() {                                  // 匹配键值对中的键
                        "name" => {                                       // 解析name字段
                            if let Value::String(s) = value {  // 解析name字段为字符串
                                name = s.clone();                         // 赋值给name变量
                            }
                        }
                        "as_name" => {
                            if let Value::String(s) = value {  
                                as_name = Some(s.clone());           // 值可以为空的字符串
                            }
                        }
                        "age" => {
                            if let Value::String(s) = value {
                                age = Some(s.clone());
                            }
                        }
                        "hobby" => {
                            if let Value::Array(a) = value {           // 解析hobby字段为列表
                                let mut hobby_list = Vec::new();       // 用于存储解析后的hobby列表
                                for v in a {                    // 循环遍历hobby列表中的元素
                                    if let Value::String(s) = v {      // 解析hobby列表中的元素为字符串
                                        hobby_list.push(s.clone());    // 列表元素添加到hobby_list中
                                    }
                                }
                                hobby = Some(serde_json::to_string(&hobby_list)?);    // 将hobby_list转换为字符串并赋值给hobby变量
                            }
                        }
                        "grade" => {
                            if let Value::Object(o) = value {  // 解析grade字段为字典
                                let mut grade_map = HashMap::new();                   // 用于存储解析后的grade字典
                                for (k, v) in o {                              // 循环遍历grade字典中的键值对
                                    if let Value::String(n) = v {                     // 解析grade字典中的值为字符串
                                        grade_map.insert(k.clone(), n.clone());       // 字典键值对添加到grade_map中  
                                    }
                                }
                                grade = Some(serde_json::to_string(&grade_map)?);     // 将grade_map转换为字符串并赋值给grade变量
                            }
                        }
                        "membe" => {
                            if let Value::Bool(b) = value {                    // 解析membe字段为布尔值
                                membe = Some(b.to_string());                         // 将布尔值转换为字符串并赋值给membe变量
                            }
                        }
                        _ => continue,  // 忽略其他字段
                    }
                }
                conn.execute(
                    "INSERT INTO test_table (name, as_name, age, hobby, grade, membe) VALUES (?1, ?2, ?3, ?4, ?5, ?6)",
                    params![name, as_name, age, hobby, grade, membe],
                )?;
            }
        }
    }
    Ok(())
}
相关推荐
树下水月2 小时前
python 连接hive2 数据库
开发语言·数据库·python
Ustinian_3102 小时前
【HTML】前端工具箱实现【文本处理/JSON工具/加解密/校验和/ASCII/时间戳转换等】【附完整源代码】
前端·html·json
在人间负债^2 小时前
Rust 实战项目:TODO 管理器
开发语言·后端·rust
s9123601012 小时前
【Rust】使用lldb 调试core dump
前端·javascript·rust
爱吃烤鸡翅的酸菜鱼2 小时前
用【rust】实现命令行音乐播放器
开发语言·后端·rust
全栈陈序员2 小时前
用Rust和Bevy打造2D平台游戏原型
开发语言·rust·游戏引擎·游戏程序
黛琳ghz2 小时前
用 Rust 从零构建高性能文件加密工具
开发语言·后端·rust
悟世君子2 小时前
Rust 开发环境搭建
开发语言·后端·rust
DARLING Zero two♡2 小时前
用Rust构建一个OCR命令行工具
数据库·rust·ocr