{"id":30602116,"url":"https://github.com/zhinjs/segment-matcher","last_synced_at":"2026-01-20T16:56:22.232Z","repository":{"id":304129087,"uuid":"1017851964","full_name":"zhinjs/segment-matcher","owner":"zhinjs","description":"一个强大的 OneBot12 消息段命令解析器，支持 TypeScript 和双格式（ESM/CJS）输出","archived":false,"fork":false,"pushed_at":"2025-08-25T04:08:02.000Z","size":11260,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-25T05:52:13.439Z","etag":null,"topics":["bun","command","commonjs","esm","node","onebot"],"latest_commit_sha":null,"homepage":"https://segment-matcher.pages.dev/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zhinjs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":null}},"created_at":"2025-07-11T07:44:02.000Z","updated_at":"2025-08-25T04:08:06.000Z","dependencies_parsed_at":"2025-07-11T11:09:38.974Z","dependency_job_id":"20254639-3270-427e-b211-5f8a8ffcd7cb","html_url":"https://github.com/zhinjs/segment-matcher","commit_stats":null,"previous_names":["lc-cn/onebot-commander","zhinjs/segment-matcher"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/zhinjs/segment-matcher","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zhinjs%2Fsegment-matcher","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zhinjs%2Fsegment-matcher/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zhinjs%2Fsegment-matcher/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zhinjs%2Fsegment-matcher/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zhinjs","download_url":"https://codeload.github.com/zhinjs/segment-matcher/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zhinjs%2Fsegment-matcher/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272784468,"owners_count":24992459,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-29T02:00:10.610Z","response_time":87,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bun","command","commonjs","esm","node","onebot"],"created_at":"2025-08-30T00:14:04.042Z","updated_at":"2026-01-20T16:56:22.226Z","avatar_url":"https://github.com/zhinjs.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Segment Matcher\n\n[![npm version](https://img.shields.io/npm/v/segment-matcher.svg)](https://www.npmjs.com/package/segment-matcher)\n[![npm downloads](https://img.shields.io/npm/dm/segment-matcher.svg)](https://www.npmjs.com/package/segment-matcher)\n[![License](https://img.shields.io/npm/l/segment-matcher.svg)](https://github.com/zhinjs/segment-matcher/blob/main/LICENSE)\n[![Test Coverage](https://img.shields.io/badge/coverage-91%25-brightgreen.svg)](https://github.com/zhinjs/segment-matcher)\n[![Node.js Version](https://img.shields.io/node/v/segment-matcher.svg)](https://nodejs.org/)\n\n消息段匹配器 - 高性能、类型安全的消息段模式匹配库，支持 ESM/CJS 双格式。\n\n## 📖 文档\n\n- [📚 完整文档](https://segment-matcher.pages.dev/) - 详细的 API 文档和使用指南\n\n## ✨ 特性\n\n- 🎯 **精确匹配**: 支持复杂的消息段模式匹配，包括字面量、类型化字面量、参数等\n- ⚡ **高性能**: \n  - 优化的匹配算法\n  - 智能缓存系统（类型检查缓存、模式解析缓存）\n  - 针对大小数组的优化策略\n- 🔧 **灵活配置**: \n  - 支持自定义类型化字面量字段映射\n  - 支持多字段优先级映射\n  - 支持动态字段提取\n- 🛡️ **类型安全**: \n  - 完整的 TypeScript 类型定义\n  - 运行时类型检查\n  - 智能类型推导\n- 🔗 **模块化设计**: \n  - 清晰的模块划分\n  - 低耦合高内聚\n  - 易于扩展\n- 📦 **双格式支持**: \n  - ESM (ECMAScript Modules)\n  - CommonJS\n- 🧪 **测试完善**: \n  - 91%+ 测试覆盖率\n  - 完整的单元测试\n  - 边界情况测试\n  - 性能测试\n- 🎨 **丰富的类型系统**: \n  - 数字类型 (`number`) - 整数或浮点数\n  - 整数类型 (`integer`) - 仅整数\n  - 浮点数类型 (`float`) - 必须带小数点\n  - 布尔类型 (`boolean`) - true/false\n  - 单词类型 (`word`) - 非空格字符序列 ⭐ 新增\n  - 文本类型 (`text`) - 支持引号包裹 ⭐ 增强\n- 📝 **参数系统**: \n  - 必需参数 (`\u003cparam:type\u003e`)\n  - 可选参数 (`[param:type]`)\n  - 带默认值的可选参数 (`[param:type=default]`)\n  - 剩余参数 (`[...rest:type]`)\n- 🔄 **字段映射**: \n  - 单字段映射\n  - 多字段优先级映射\n  - 动态字段提取\n- 🚦 **智能空格处理**: \n  - 参数间的单个空格自动处理 ⭐ 新增\n  - 多个空格视为字面量精确匹配\n  - 支持单个文本段自动提取多个参数 ⭐ 新增\n- 💬 **引号支持**: \n  - 单引号和双引号 ⭐ 新增\n  - 嵌套不同类型引号 ⭐ 新增\n  - 多个 text 参数明确边界 ⭐ 新增\n\n## 🚀 快速开始\n\n### 安装\n\n```bash\nnpm install segment-matcher\n```\n\n### 基础用法\n\n```typescript\nimport { SegmentMatcher } from 'segment-matcher';\n\n// 创建消息段匹配器（注意空格敏感）\nconst matcher = new SegmentMatcher('hello \u003cname:text\u003e'); // \"hello \" 后面的空格\n\n// 匹配消息段并处理结果\nconst segments = [\n  { type: 'text', data: { text: 'hello Alice' } } // 注意 \"hello \" 后面的空格\n];\n\nconst result = matcher.match(segments);\nif (result) {\n  console.log('匹配的消息段:', result.matched);\n  console.log('提取的参数:', result.params);\n  console.log('剩余的消息段:', result.remaining);\n}\n```\n\n### 🎨 高级特性\n\n#### 1. 单个文本段多参数提取 ⭐ 新功能\n\n```typescript\n// 支持从单个连续文本段中提取多个参数\nconst matcher = new SegmentMatcher('move [x:number=0] [y:number=0]');\n\n// 单个文本段，匹配器会自动提取参数\nconst result = matcher.match([\n  { type: 'text', data: { text: 'move 10 20' } }\n]);\n\nconsole.log(result.params); // { x: 10, y: 20 }\n```\n\n#### 2. word 类型 - 非空格字符 ⭐ 新类型\n\n```typescript\n// word 类型可以提取多个单词参数，不会像 text 那样贪婪匹配\nconst matcher = new SegmentMatcher('config [key:word=name] [value:word=default]');\n\nconst result = matcher.match([\n  { type: 'text', data: { text: 'config database mysql' } }\n]);\n\nconsole.log(result.params); // { key: 'database', value: 'mysql' }\n```\n\n#### 3. 引号支持 - 包含空格的文本 ⭐ 新功能\n\n```typescript\n// 使用引号可以提取多个包含空格的 text 参数\nconst matcher = new SegmentMatcher('post [title:text=Untitled] [tags:text=none]');\n\n// 使用双引号\nconst result1 = matcher.match([\n  { type: 'text', data: { text: 'post \"My Article Title\" \"tag1 tag2 tag3\"' } }\n]);\nconsole.log(result1.params); \n// { title: 'My Article Title', tags: 'tag1 tag2 tag3' }\n\n// 使用单引号\nconst result2 = matcher.match([\n  { type: 'text', data: { text: \"post 'Quick Tips' 'tutorial'\" } }\n]);\nconsole.log(result2.params); \n// { title: 'Quick Tips', tags: 'tutorial' }\n\n// 嵌套不同类型引号\nconst result3 = matcher.match([\n  { type: 'text', data: { text: `post \"It's great\" 'He said \"hello\"'` } }\n]);\nconsole.log(result3.params); \n// { title: \"It's great\", tags: 'He said \"hello\"' }\n```\n\n#### 4. 类型化字面量\n\n```typescript\n// 匹配特定类型的消息段\nconst matcher = new SegmentMatcher('{text:hello}{at:123456}');\n\n// 匹配结果包含完整的消息段信息\nconst result = matcher.match([\n  { type: 'text', data: { text: 'hello' } },\n  { type: 'at', data: { user_id: 123456 } }\n]);\n```\n\n#### 5. 剩余参数匹配\n\n```typescript\n// 收集所有剩余的图片\nconst matcher = new SegmentMatcher('图片[...images:image]');\n\nconst result = matcher.match([\n  { type: 'text', data: { text: '图片' } },\n  { type: 'image', data: { file: '1.jpg' } },\n  { type: 'image', data: { file: '2.jpg' } }\n]);\n\n// result.params.images 将包含所有图片的 URL\n```\n\n#### 6. 自定义字段映射\n\n```typescript\n// 自定义字段映射规则\nconst matcher = new SegmentMatcher('图片\u003cimg:image\u003e', {\n  image: ['url', 'file', 'src']  // 按优先级尝试这些字段\n});\n\n// 匹配时会按照指定的字段优先级提取值\nconst result = matcher.match([\n  { type: 'text', data: { text: '图片' } },\n  { type: 'image', data: { url: 'https://example.com/image.jpg' } }\n]);\n```\n\n#### 7. 智能空格处理 ⭐ 新功能\n\n```typescript\n// 参数间的单个空格会被自动处理（可选）\nconst matcher = new SegmentMatcher('cmd [a:number] [b:number]');\n\n// 以下两种输入都可以匹配\nmatcher.match([{ type: 'text', data: { text: 'cmd 10 20' } }]);   // 有空格 ✅\nmatcher.match([{ type: 'text', data: { text: 'cmd 1020' } }]);     // 紧贴也可以 ✅\n\n// 但多个空格会被视为字面量\nconst strictMatcher = new SegmentMatcher('cmd  [a:number]'); // 两个空格\nstrictMatcher.match([{ type: 'text', data: { text: 'cmd  10' } }]);  // 必须两个空格 ✅\nstrictMatcher.match([{ type: 'text', data: { text: 'cmd 10' } }]);   // 一个空格 ❌\n```\n\n### 📚 类型对比指南\n\n| 场景 | 推荐类型 | 示例 | 说明 |\n|------|---------|------|------|\n| 单个单词 | `word` | `[name:word]` | 不包含空格的字符串 |\n| 包含空格的文本 | `text` + 引号 | `[msg:text]` 输入 `\"hello world\"` | 明确边界 |\n| 最后一个参数 | `text` | `[msg:text]` | 贪婪匹配剩余内容 |\n| 数字 | `number` | `[count:number]` | 整数或浮点数 |\n| 整数 | `integer` | `[age:integer]` | 只接受整数 |\n| 浮点数 | `float` | `[price:float]` | 必须带小数点 |\n| 布尔值 | `boolean` | `[flag:boolean]` | true/false |\n\n### ⚠️ 注意事项\n\n1. **智能空格处理** ⭐ 更新\n   - 参数间的单个空格自动处理（可选匹配）\n   - 多个连续空格视为字面量（必须精确匹配）\n   - 支持单个文本段自动提取多个参数\n\n2. **引号使用建议** ⭐ 新增\n   - 使用引号包裹包含空格的 text 参数\n   - 双引号内可以使用单引号，反之亦然\n   - 相同类型的引号不能嵌套（如 `\"a\"b\"` 会在第二个 `\"` 处结束）\n\n3. **类型选择** ⭐ 新增\n   - 多个单词参数优先使用 `word` 类型\n   - 需要包含空格时使用 `text` + 引号\n   - `text` 类型放在参数列表末尾可以省略引号\n\n4. **类型安全**\n   - 建议启用 TypeScript 的严格模式\n   - 使用类型断言时要小心\n\n5. **性能优化**\n   - 对于频繁使用的模式，重用 `SegmentMatcher` 实例\n   - 合理使用字段映射来避免不必要的字段访问\n\n## 🧪 测试\n\n```bash\n# 运行测试\nnpm test\n\n# 运行测试并生成覆盖率报告\nnpm run test:coverage\n```\n\n## 📦 构建\n\n```bash\n# 构建项目\nnpm run build\n\n# 清理构建产物\nnpm run clean\n```\n\n## 📄 许可证\n\nMIT License - 查看 [LICENSE](LICENSE) 文件了解详情。\n\n## 🔗 相关链接\n- [GitHub 仓库](https://github.com/zhinjs/segment-matcher)\n- [npm 包](https://www.npmjs.com/package/segment-matcher)\n- [在线文档](https://segment-matcher.pages.dev/)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzhinjs%2Fsegment-matcher","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzhinjs%2Fsegment-matcher","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzhinjs%2Fsegment-matcher/lists"}