use fancy_regex::Regex;
use super::lexicon;
use super::re::{compile, compile_i};
use super::text::regex_alternation;
use std::sync::LazyLock;
pub(crate) static UNIT_ALT: LazyLock<String> =
LazyLock::new(|| regex_alternation(lexicon::UNITS.iter().map(|u| u.key)));
pub(crate) static COUNTED_NOUN_ALT: LazyLock<String> =
LazyLock::new(|| regex_alternation(lexicon::COUNTED_NOUNS.iter().map(|n| n.key)));
pub(crate) static CURRENCY_TOKEN_ALT: LazyLock<String> = LazyLock::new(|| {
let mut keys: Vec<&str> = vec!["грн"];
for entry in lexicon::CURRENCIES.iter() {
keys.push(entry.code);
if !entry.symbol.is_empty() {
keys.push(entry.symbol);
}
}
format!("(?:{})", regex_alternation(keys))
});
pub(crate) static CURRENCY_CODE_ALT: LazyLock<String> =
LazyLock::new(|| regex_alternation(lexicon::CURRENCIES.iter().map(|c| c.code)));
pub(crate) const MONTH_ALT: &str = concat!(
"січня|січ\\.|лютого|лют\\.|березня|бер\\.|квітня|квіт\\.|травня|трав\\.|червня|черв\\.|",
"липня|лип\\.|серпня|серп\\.|вересня|вер\\.|жовтня|жовт\\.|листопада|лист\\.|грудня|груд\\.|",
"Січня|Лютого|Березня|Квітня|Травня|Червня|Липня|Серпня|Вересня|Жовтня|Листопада|Грудня"
);
pub(crate) const MULTIPLIER_TOKEN: &str = r"(?:тис|млн|млрд|трлн)\.?";
pub(crate) const SIGNED_NUMBER: &str = r"(?:\+|-|−|–|—)?(?:\d+(?:[.,]\d+)?|[.,]\d+)";
pub(crate) const RANGE_SEPARATOR: &str = r"(?:-|−|‐|‑|‒|–|—|…)";
pub(crate) const RANGE_PREFIX: &str = r"(^|[\s(\[{:;,.!?=]|(?:[-–—]\s+))";
pub(crate) static DATE_DAY_RANGE_RE: LazyLock<Regex> = LazyLock::new(|| {
compile(&format!(
concat!(
r"\b(\d{{1,2}})\s*(?:-|−|–|—)\s*(\d{{1,2}})\s+({})\s+(\d{{3,4}})",
r"(?:\s+року(?![А-Яа-яЄєІіЇїҐґ])|\s*р\.(?![а-яіїєґ]))?"
),
MONTH_ALT
))
});
pub(crate) static DATE_SPELLED_RE: LazyLock<Regex> = LazyLock::new(|| {
compile_i(&format!(
concat!(
r"\b(\d{{1,2}})\s+({})\s+(\d{{3,4}})",
r"(?:\s+року(?![А-Яа-яЄєІіЇїҐґ])|\s*р\.(?![а-яіїєґ]))?"
),
MONTH_ALT
))
});
pub(crate) static CASE_PREP_RE: LazyLock<Regex> = LazyLock::new(|| {
compile(&format!(
concat!(
r"(^|[^А-Яа-яЄєІіЇїҐґ-])(Близько|близько|Після|після|Протягом|протягом|Впродовж|впродовж|",
r"Упродовж|упродовж|Менше|менше|Більше|більше|Серед|серед|Перед|перед|Між|між|Над|над|",
r"Під|під|При|при|Без|без|Від|від|До|до|Із|із|З|з|Об|об|К|к|О|о)",
r"\s+(\d+)(?:\s*({})(\.?))?(?!\s*%)(?![\d.,:%–—-])(?![A-Za-zА-Яа-яЄєІіЇїҐґ])"
),
*UNIT_ALT
))
});
pub(crate) static COUNTED_PONAD_RE: LazyLock<Regex> = LazyLock::new(|| {
compile(&format!(
r"(^|[^А-Яа-яЄєІіЇїҐґ\d])(Понад|понад)\s+([1-9]\d{{0,5}})\s+({})(?![А-Яа-яЄєІіЇїҐґ])",
*COUNTED_NOUN_ALT
))
});
pub(crate) static COUNTED_GENITIVE_RE: LazyLock<Regex> = LazyLock::new(|| {
compile(&format!(
concat!(
r"(^|[^А-Яа-яЄєІіЇїҐґ\d])(Близько|близько|Більше|більше|Менше|менше|Серед|серед|До|до|",
r"Від|від|Без|без|Після|після|Протягом|протягом|Впродовж|впродовж|Упродовж|упродовж|Із|із)",
r"\s+([1-9]\d{{0,5}})\s+({})(?![А-Яа-яЄєІіЇїҐґ])"
),
*COUNTED_NOUN_ALT
))
});
pub(crate) static COUNTED_NOUNS_RE: LazyLock<Regex> = LazyLock::new(|| {
compile_i(&format!(
r"(^|[^А-Яа-яЄєІіЇїҐґ\d/])([1-9]\d{{0,5}})\s+({})(?![А-Яа-яЄєІіЇїҐґ])",
*COUNTED_NOUN_ALT
))
});
pub(crate) static MEASUREMENTS_RE: LazyLock<Regex> = LazyLock::new(|| {
compile(&format!(
r"(^|[^\d.,+\-])([+\-]?\d+(?:[.,]\d+)?)\s*({})(\.?)(?![A-Za-zА-Яа-яЄєІіЇїҐґ])",
*UNIT_ALT
))
});
pub(crate) static SYMBOL_CURRENCY_PREFIX_RE: LazyLock<Regex> = LazyLock::new(|| {
compile(&format!(r"({})\s*(\d+(?:[.,]\d+)?)\s*({MULTIPLIER_TOKEN})", *CURRENCY_TOKEN_ALT))
});
pub(crate) static SYMBOL_CURRENCY_SUFFIX_RE: LazyLock<Regex> = LazyLock::new(|| {
compile(&format!(r"(\d+(?:[.,]\d+)?)\s*({MULTIPLIER_TOKEN})\s*({})", *CURRENCY_TOKEN_ALT))
});