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(())
}