use std::sync::LazyLock;
use regex::bytes::Regex;
static STR_RE: LazyLock<Regex> =
LazyLock::new(|| Regex::new(r#"(?-u)"[^"]*"|'[^']*'|`[^`]*`"#).unwrap());
static NUM_RE: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"(?-u)\b\d+\b").unwrap());
static IDENT_RE: LazyLock<Regex> =
LazyLock::new(|| Regex::new(r"(?-u)[A-Za-z_][A-Za-z0-9_\-]{3,}").unwrap());
static WS_RE: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"(?-u)\s+").unwrap());
pub fn normalize_line(line: &[u8]) -> Vec<u8> {
let s = STR_RE.replace_all(line, b"\"S\"".as_slice());
let s = NUM_RE.replace_all(&s, b"N".as_slice());
let s = IDENT_RE.replace_all(&s, b"I".as_slice());
let s = WS_RE.replace_all(&s, b" ".as_slice());
trim_ascii(&s).to_vec()
}
fn trim_ascii(s: &[u8]) -> &[u8] {
let start = s
.iter()
.position(|b| !b.is_ascii_whitespace())
.unwrap_or(s.len());
let end = s
.iter()
.rposition(|b| !b.is_ascii_whitespace())
.map_or(start, |e| e + 1);
&s[start..end]
}