47 lines
1.4 KiB
Python
47 lines
1.4 KiB
Python
|
|
from __future__ import annotations
|
|||
|
|
|
|||
|
|
import re
|
|||
|
|
from typing import Any
|
|||
|
|
|
|||
|
|
|
|||
|
|
def parse_number_value(value: Any) -> float | None:
|
|||
|
|
if isinstance(value, (int, float)):
|
|||
|
|
return float(value)
|
|||
|
|
text = re.sub(r"[,,\s元¥¥]", "", str(value or ""))
|
|||
|
|
match = re.search(r"-?\d+(?:\.\d+)?", text)
|
|||
|
|
if not match:
|
|||
|
|
return None
|
|||
|
|
try:
|
|||
|
|
return float(match.group(0))
|
|||
|
|
except ValueError:
|
|||
|
|
return None
|
|||
|
|
|
|||
|
|
|
|||
|
|
def compare_numbers(left: float, right: float, compare: str) -> bool:
|
|||
|
|
if compare in {"gt", ">", "greater_than"}:
|
|||
|
|
return left > right
|
|||
|
|
if compare in {"gte", ">=", "greater_or_equal"}:
|
|||
|
|
return left >= right
|
|||
|
|
if compare in {"lt", "<", "less_than"}:
|
|||
|
|
return left < right
|
|||
|
|
if compare in {"lte", "<=", "less_or_equal"}:
|
|||
|
|
return left <= right
|
|||
|
|
if compare in {"eq", "=", "equals"}:
|
|||
|
|
return left == right
|
|||
|
|
return left > right
|
|||
|
|
|
|||
|
|
|
|||
|
|
def duplicate_text_values(values: list[Any]) -> list[str]:
|
|||
|
|
seen: set[str] = set()
|
|||
|
|
duplicates: list[str] = []
|
|||
|
|
for value in values:
|
|||
|
|
items = value if isinstance(value, (list, tuple, set)) else [value]
|
|||
|
|
for item in items:
|
|||
|
|
text = re.sub(r"\s+", "", str(item or "")).strip().lower()
|
|||
|
|
if not text:
|
|||
|
|
continue
|
|||
|
|
if text in seen and text not in duplicates:
|
|||
|
|
duplicates.append(text)
|
|||
|
|
seen.add(text)
|
|||
|
|
return duplicates
|