File size: 2,508 Bytes
73d02ec
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
"""
query_parse.py — pull price constraints out of a natural-language prompt.

"bird pendant under 15000"  -> clean="bird pendant", max_price=15000
"rose gold ring above 5k"   -> clean="rose gold ring", min_price=5000
"anklet between 1000 and 3000" -> min_price=1000, max_price=3000

Deterministic (regex) so the demo behaves predictably — no LLM needed. The
cleaned prompt (price words removed) is what we embed, so the vector focuses on
the product, not the number.
"""

import re


def _to_number(raw: str) -> float:
    """'15,000' -> 15000, '15k' -> 15000, '1.5k' -> 1500."""
    s = raw.lower().replace(",", "").replace("₹", "").replace("rs", "").strip()
    mult = 1
    if s.endswith("k"):
        mult = 1000
        s = s[:-1]
    elif s.endswith("l") or s.endswith("lakh"):
        mult = 100000
        s = s.rstrip("lakh").strip()
    try:
        return float(s) * mult
    except ValueError:
        return None


# A price token like  15000 | 15,000 | 15k | ₹15000 | rs 2.5k
_NUM = r"(?:₹\s*|rs\.?\s*)?(\d[\d,]*\.?\d*\s*(?:k|l|lakh)?)"

_BETWEEN = re.compile(r"between\s+" + _NUM + r"\s+(?:and|to|-)\s+" + _NUM, re.I)
_UNDER = re.compile(
    r"(?:under|below|less than|within|upto|up to|max(?:imum)?|no more than|<=?)\s+" + _NUM, re.I)
_OVER = re.compile(
    r"(?:over|above|more than|min(?:imum)?|at least|starting (?:from|at)|>=?)\s+" + _NUM, re.I)


def parse_constraints(prompt: str):
    """Return (clean_prompt, min_price, max_price). Bounds are None if absent."""
    text = prompt
    min_price = max_price = None

    m = _BETWEEN.search(text)
    if m:
        a, b = _to_number(m.group(1)), _to_number(m.group(2))
        if a is not None and b is not None:
            min_price, max_price = min(a, b), max(a, b)
        text = _BETWEEN.sub(" ", text)

    m = _UNDER.search(text)
    if m:
        v = _to_number(m.group(1))
        if v is not None:
            max_price = v
        text = _UNDER.sub(" ", text)

    m = _OVER.search(text)
    if m:
        v = _to_number(m.group(1))
        if v is not None:
            min_price = v
        text = _OVER.sub(" ", text)

    clean = re.sub(r"\s{2,}", " ", text).strip(" .,-") or prompt
    return clean, min_price, max_price


if __name__ == "__main__":
    for q in ["bird pendant under 15000", "rose gold ring above 5k",
              "anklet between 1000 and 3000", "gold studs upto ₹20,000",
              "silver bracelet less than 2.5k", "diamond necklace"]:
        print(q, "->", parse_constraints(q))