"""项目命令解析辅助函数。""" from __future__ import annotations import re from ..utils.title import compact_title def normalize_project_title_candidate(candidate: str) -> str: cleaned = re.sub(r"\s+", " ", str(candidate or "")).strip(" []【】()()::\"'“”") if not cleaned: return "" cleaned = re.sub( r"^(?:名称|名字|项目名|需求名)(?:叫|是|为|名为|名称为|名字为|名称是|名字是|名称叫|名字叫)\s*", "", cleaned, flags=re.IGNORECASE, ).strip(" []【】()()::\"'“”") if not cleaned: return "" cleaned = re.sub( r"^(?:(?:项目|需求)(?:名字|名称|名)?(?:叫|是|为|名为|名称为|名字为|名称叫|名字叫)?|(?:项目|需求)?(?:名为|名称为|名字为|名称是|名字是|名称叫|名字叫|叫|为))\s*", "", cleaned, flags=re.IGNORECASE, ).strip(" []【】()()::\"'“”") if not cleaned: return "" normalized = re.sub(r"\s+", "", cleaned).lower() generic_tokens = { "项目", "一个项目", "新项目", "项目列表", "项目列表里面", "项目库", "项目台账", "项目主数据", "pmflow", "pmflow项目列表", } if normalized in generic_tokens: return "" if normalized.startswith(("在项目列表", "到项目列表", "进项目列表", "在pmflow", "到pmflow", "进pmflow")): return "" return compact_title(cleaned, max_len=24) def extract_project_create_title(text: str) -> str: cleaned = re.sub(r"\s+", " ", str(text or "")).strip() if not cleaned: return "" quoted_match = re.search(r"(?:项目|新项目)[^\"“”']{0,10}[\"“”']([^\"“”']{2,40})[\"“”']", cleaned) if quoted_match: return normalize_project_title_candidate(quoted_match.group(1)) for pattern in ( r"(?:项目|需求)(?:名字|名称|名)?(?:叫|名为|名称是|名称为|是|为)[::,,\s]*(.+)", r"(?:帮我|请|麻烦|给我)?(?:新增|增加|添加|创建|新建|建立|开个|开一个|建个|建一个|做个|做一个|加个|加一个)(?:一个|个)?项目(?:叫|名为|名称是|名称为|是|为)?[::,,\s]*(.+)", r"(?:新增|增加|添加|创建|新建|建立)项目[::,,\s]*(.+)", ): match = re.search(pattern, cleaned, re.IGNORECASE) if not match: continue candidate = re.sub(r"[,。,.;;!??].*$", "", match.group(1)).strip(" []【】()()::\"'“”") candidate = re.sub(r"^(?:一个|个|新项目|项目|需求)\s*", "", candidate, flags=re.IGNORECASE) candidate = re.sub( r"^(?:(?:项目|需求)(?:名字|名称|名)?(?:叫|是|为|名为|名称为|名字为|名称叫|名字叫)?|(?:项目|需求)?(?:名为|名称为|名字为|名称是|名字是|名称叫|名字叫|叫|为))\s*", "", candidate, flags=re.IGNORECASE, ) if candidate: return normalize_project_title_candidate(candidate) return "" def extract_project_create_description(*, instruction: str, title: str) -> str: cleaned = re.sub(r"\s+", " ", str(instruction or "")).strip() if not cleaned: return "" if title: cleaned = cleaned.replace(title, "", 1).strip(" ,,::") cleaned = re.sub( r"^(?:帮我|请|麻烦|给我)?(?:新增|增加|添加|创建|新建|建立|开个|开一个|建个|建一个|做个|做一个|加个|加一个)(?:一个|个)?项目(?:叫|名为|名称是|名称为|是|为)?", "", cleaned, flags=re.IGNORECASE, ).strip(" ,,::") if not cleaned: return "" return cleaned[:4000]