text-search-engine
4
总安装量
3
周安装量
#49931
全站排名
安装命令
npx skills add https://github.com/cjinhuo/text-search-engine --skill text-search-engine
Agent 安装分布
trae
3
mcpjam
2
claude-code
2
junie
2
windsurf
2
zencoder
2
Skill 文档
Text Search Engine æ¥å ¥æå
æ¤ skill 帮å©ä½ å° text-search-engine SDK éæå°é¡¹ç®ä¸ã该 SDK æ¯ä¸ä¸ªåºäºå¨æè§åçææ¬æç´¢å¼æï¼æ¯æä¸è±ææ··åæ¨¡ç³æç´¢ï¼è¿åæéæé«çå¹é ç»æã
å®è£
npm i text-search-engine
åæ¶æ¯æ Node.js å Web ç¯å¢ã
æ ¸å¿ API
1. search(source, query, options?) – 主æç´¢å½æ°
è¿åå¹é
ä½ç½®çç´¢å¼èå´æ°ç» [start, end][]ï¼æ å¹é
æ¶è¿å undefinedã
åºæ¬ç¨æ³
import { search } from 'text-search-engine'
// çº¯è±ææç´¢
search('nonode', 'no') // [[0, 1]] - å¹é
'no'
search('nonode', 'nod') // [[2, 4]] - å¹é
'nod'
search('nonode', 'noe') // [[0, 1], [5, 5]] - å¹é
'no' + 'e'
// çº¯ä¸ææç´¢ï¼æ¯ææ¼é³ï¼
search('å°è¡¨æå¼ºåç«¯çæ§å¹³å°', 'jk') // [[6, 7]] - å¹é
'çæ§'
search('å°è¡¨æå¼ºåç«¯çæ§å¹³å°', 'qianduapt') // [[4, 5], [8, 9]] - å¹é
'å端' + 'å¹³å°'
// ä¸è±ææ··åæç´¢
search('Node.js æå¼ºçæ§å¹³å° V9', 'nodejk') // [[0, 3], [10, 11]] - å¹é
'Node' + 'çæ§'
ç©ºæ ¼åéæç´¢
æ·»å ç©ºæ ¼ä½¿æ¯ä¸ªè¯ç¬ç«å¹é ï¼ä»å¤´å¼å§ï¼
search('Node.js æå¼ºçæ§å¹³å° V9', 'jknode') // undefined
search('Node.js æå¼ºçæ§å¹³å° V9', 'jk node') // [[10, 11], [0, 3]] - å¯ä»¥å¹é
ï¼
2. é ç½®é项
| é项 | é»è®¤å¼ | 说æ |
|---|---|---|
mergeSpaces |
true |
å°å¹é ç»æä¸çç©ºæ ¼å并为è¿ç»èå´ |
strictnessCoefficient |
undefined |
ä¸¥æ ¼ç³»æ°ï¼0-1ï¼ï¼å¹é
åç¬¦æ° â¤ ceil(query.length * coefficient) æ¶è¿å undefined |
isCharConsecutive |
false |
è¦æ±å¹é çåç¬¦å¿ é¡»è¿ç» |
strictCase |
false |
åºå大å°åå¹é |
示ä¾
// mergeSpaces - åå¹¶ç©ºæ ¼
search('chrome åºç¨ååº', 'meyinyon', { mergeSpaces: false }) // [[4, 5], [7, 8]]
search('chrome åºç¨ååº', 'meyinyon', { mergeSpaces: true }) // [[4, 8]]
// strictnessCoefficient - ä¸¥æ ¼ç³»æ°
search('Node.js æå¼ºçæ§å¹³å° V8', 'nozjk', { strictnessCoefficient: 0.5 }) // [[0, 1], [8, 8], [10, 11]]
search('Node.js æå¼ºçæ§å¹³å° V8', 'nozjk', { strictnessCoefficient: 0.4 }) // undefined
// isCharConsecutive - è¿ç»å符
search('Chinese@ä¸å½ People-人', 'chie') // [[0, 2], [4, 4]]
search('Chinese@ä¸å½ People-人', 'chie', { isCharConsecutive: true }) // undefined
// strictCase - 大å°åææ
search('Hello World', 'hello') // [[0, 4]]
search('Hello World', 'hello', { strictCase: true }) // undefined
3. highlightMatches(source, query) – å¿«éé«äº®
è¿å ANSI 转ä¹ç ï¼ç¨äºæ§å¶å°è¾åºï¼
import { highlightMatches } from 'text-search-engine'
console.log(highlightMatches('Node.js æå¼ºçæ§å¹³å° V9', 'nodev9'))
// è¾åºå¸¦é«äº®çææ¬
React ç»ä»¶
HighlightWithTarget
èªå¨å¹é å¹¶é«äº®ï¼
import { HighlightWithTarget } from 'text-search-engine/react'
function SearchResult() {
return <HighlightWithTarget source='Node.js æå¼ºçæ§å¹³å° V9' target='nodejk' />
}
HighlightWithRanges
æå¨æä¾å¹é èå´ï¼
import { HighlightWithRanges } from 'text-search-engine/react'
import { search } from 'text-search-engine'
function SearchResult() {
const ranges = search('Node.js æå¼ºçæ§å¹³å° V9', 'nodejk')
return <HighlightWithRanges source='Node.js æå¼ºçæ§å¹³å° V9' hitRanges={ranges} />
}
常è§éææ¨¡å¼
1. 带é«äº®çæç´¢å表
import { search } from 'text-search-engine'
import { HighlightWithRanges } from 'text-search-engine/react'
function SearchList({ items, query }) {
const results = items
.map(item => ({ item, ranges: search(item.name, query) }))
.filter(({ ranges }) => ranges !== undefined)
return (
<ul>
{results.map(({ item, ranges }) => (
<li key={item.id}>
<HighlightWithRanges source={item.name} hitRanges={ranges} />
</li>
))}
</ul>
)
}
2. å¤ç¨ BoundaryData è¿è¡å¤æ¬¡æç´¢
å½éè¦å¯¹å䏿°æ®æºè¿è¡å¤æ¬¡æç´¢æ¶ï¼å¯ä»¥é¢å
æå boundaryData 以æåæ§è½ï¼
import {
extractBoundaryMapping,
searchSentenceByBoundaryMapping
} from 'text-search-engine'
const source = 'Node.js æå¼ºçæ§å¹³å° V9'
// é¢å
æå boundaryDataï¼åªéæ§è¡ä¸æ¬¡ï¼
const boundaryData = extractBoundaryMapping(source)
// 夿¬¡æç´¢å¤ç¨åä¸ä¸ª boundaryData
function searchMultiple(queries) {
return queries.map(query => {
const { hitRanges, wordHitRangesMapping } = searchSentenceByBoundaryMapping(boundaryData, query)
return { query, hitRanges, wordHitRangesMapping }
}).filter(result => result.hitRanges !== undefined)
}
// 示ä¾ï¼å¯¹å䏿°æ®æºè¿è¡å¤æ¬¡æç´¢
const results = searchMultiple(['node', 'jk', 'v9', 'qianduan'])
è¿ç§æ¹å¼ç¹å«éå以ä¸åºæ¯ï¼
- æç´¢å表ä¸å¯¹æ¯ä¸ª item éè¦å¹é å¤ä¸ªå ³é®è¯
- 宿¶æç´¢å»ºè®®ï¼ç¨æ·è¾å ¥ååæ¶å¤ç¨å·²å¤ççæ°æ®
- æ¹éæç´¢ä»»å¡
3. Node.js å端æç´¢
import { search } from 'text-search-engine'
function searchDocuments(documents, query, options = {}) {
const { limit = 20, strictnessCoefficient = 0.6 } = options
const results = []
for (const doc of documents) {
const ranges = search(doc.title, query, { strictnessCoefficient })
if (ranges) {
results.push({ doc, ranges })
if (results.length >= limit) break
}
}
return results
}
æ§è½
| æ¶é´å¤æåº¦ | 空é´å¤æåº¦ | |
|---|---|---|
| æä¼ | O(M)ï¼M = æºå符串é¿åº¦ | O(M) |
| æå·® | O(M à N)ï¼N = æ¥è¯¢å符串é¿åº¦ | O(M à N) |