JavaScript实战笔记(三) 文本搜索

简介: JavaScript实战笔记(三) 文本搜索

借鉴 pdf.js 源码,实现文本搜索功能,包含大小写敏感和全字匹配选项,话不多说,直接上码

var CharacterType = {
    SPACE: 0,
    ALPHA_LETTER: 1,
    PUNCT: 2,
    HAN_LETTER: 3,
    KATAKANA_LETTER: 4,
    HIRAGANA_LETTER: 5,
    HALFWIDTH_KATAKANA_LETTER: 6,
    THAI_LETTER: 7
}
function isAlphabeticalScript(charCode) { return charCode < 0x2E80 }
function isAscii(charCode) { return (charCode & 0xFF80) === 0 }
function isAsciiAlpha(charCode) { return charCode >= 0x61 && charCode <= 0x7A || charCode >= 0x41 && charCode <= 0x5A }
function isAsciiDigit(charCode) { return charCode >= 0x30 && charCode <= 0x39 }
function isAsciiSpace(charCode) { return charCode === 0x20 || charCode === 0x09 || charCode === 0x0D || charCode === 0x0A }
function isThai(charCode) { return (charCode & 0xFF80) === 0x0E00 }
function isHan(charCode) { return charCode >= 0x3400 && charCode <= 0x9FFF || charCode >= 0xF900 && charCode <= 0xFAFF }
function isKatakana(charCode) { return charCode >= 0x30A0 && charCode <= 0x30FF }
function isHiragana(charCode) { return charCode >= 0x3040 && charCode <= 0x309F }
function isHalfwidthKatakana(charCode) { return charCode >= 0xFF60 && charCode <= 0xFF9F }
function getCharacterType(charCode) {
    if (isAlphabeticalScript(charCode)) {
        if (isAscii(charCode)) {
            if (isAsciiSpace(charCode)) { return CharacterType.SPACE }
            else if (isAsciiAlpha(charCode) || isAsciiDigit(charCode) || charCode === 0x5F) { return CharacterType.ALPHA_LETTER }
            return CharacterType.PUNCT
        }
        else if (isThai(charCode)) { return CharacterType.THAI_LETTER }
        else if (charCode === 0xA0) { return CharacterType.SPACE }
        return CharacterType.ALPHA_LETTER
    }
    if (isHan(charCode)) { return CharacterType.HAN_LETTER }
    else if (isKatakana(charCode)) { return CharacterType.KATAKANA_LETTER }
    else if (isHiragana(charCode)) { return CharacterType.HIRAGANA_LETTER }
    else if (isHalfwidthKatakana(charCode)) { return CharacterType.HALFWIDTH_KATAKANA_LETTER }
    return CharacterType.ALPHA_LETTER
}
function isEntireWord(content, matchIdx, length) {
    var startIdx = matchIdx
    if (startIdx > 0) {
        var first = content.charCodeAt(startIdx)
        var limit = content.charCodeAt(startIdx - 1)
        if (getCharacterType(first) === getCharacterType(limit)) {
            return false
        }
    }
    var endIdx = matchIdx + length - 1
    if (endIdx < content.length - 1) {
        var last = content.charCodeAt(endIdx)
        var limit = content.charCodeAt(endIdx + 1)
        if (getCharacterType(last) === getCharacterType(limit)) {
            return false
        }
    }
    return true
}
/**
 * 在特定文本中搜索指定内容,返回结果索引
 * @param  {String}   query         要查询的内容
 * @param  {String}   content       待搜索的文本
 * @param  {Boolean}  caseSensitive 大小写敏感
 * @param  {Boolean}  entireWord    全字匹配
 * @return {[Number]}               结果索引
 */
function search(query, content, caseSensitive, entireWord) {
    if (query.length === 0) {
        return
    }
    if (!caseSensitive) {
        query = query.toLowerCase()
        content = content.toLowerCase()
    }
    var matchRst = [], matchIdx = -query.length, queryLen = query.length
    while (true) {
        matchIdx = content.indexOf(query, matchIdx + queryLen)
        if (matchIdx === -1) {
            break
        }
        if (entireWord && !isEntireWord(content, matchIdx, queryLen)) {
            continue
        }
        matchRst.push(matchIdx)
    }
    return matchRst
}


一个用于测试的例子

var content = 'Say Hello To Tomorrow. Say Goodbye To Yesterday.'
var query = 'say'
var result = search(query, content, true, false)
console.log(result) // []
var result = search(query, content, false, false)
console.log(result) // [0, 23]
var query = 'Good'
var result = search(query, content, true, false)
console.log(result) // [27]
var result = search(query, content, true, true)
console.log(result) // []


目录
相关文章
|
1月前
|
自然语言处理 JavaScript 前端开发
深入理解JavaScript中的闭包:原理与实战
【10月更文挑战第12天】深入理解JavaScript中的闭包:原理与实战
|
1月前
|
JavaScript 前端开发 程序员
前端学习笔记——node.js
前端学习笔记——node.js
43 0
|
20天前
|
自然语言处理 JavaScript 前端开发
[JS]同事看了我做的this笔记,直摇头,坦言:我还是参考启发博文吧
本文介绍了JavaScript中`this`关键字的重要性和使用规则。作者回顾了早期笔记,总结了`this`指向的各种情况,并分享了最新的理解。文章强调了`this`在不同上下文中的指向,包括对象方法、全局函数、箭头函数等,并提供了改变`this`指向的方法。适合JavaScript开发者参考。
40 2
|
29天前
|
JavaScript 前端开发 开发者
探索JavaScript原型链:深入理解与实战应用
【10月更文挑战第21天】探索JavaScript原型链:深入理解与实战应用
31 1
|
1月前
|
SQL 前端开发 JavaScript
Nest.js 实战 (十五):前后端分离项目部署的最佳实践
这篇文章介绍了如何使用现代前端框架Vue3和后端Node.js框架Nest.js实现的前后端分离架构的应用,并将其部署到生产环境。文章涵盖了准备阶段,包括云服务器的设置、1Panel面板的安装、数据库的安装、域名的实名认证和备案、SSL证书的申请。在部署Node服务环节,包括了Node.js环境的创建、数据库的配置、用户名和密码的设置、网站信息的填写、静态网站的部署、反向代理的配置以及可能遇到的常见问题。最后,作者总结了部署经验,并希望对读者有所帮助。
142 11
|
1月前
|
人工智能 JavaScript 网络安全
ToB项目身份认证AD集成(三完):利用ldap.js实现与windows AD对接实现用户搜索、认证、密码修改等功能 - 以及针对中文转义问题的补丁方法
本文详细介绍了如何使用 `ldapjs` 库在 Node.js 中实现与 Windows AD 的交互,包括用户搜索、身份验证、密码修改和重置等功能。通过创建 `LdapService` 类,提供了与 AD 服务器通信的完整解决方案,同时解决了中文字段在 LDAP 操作中被转义的问题。
|
2月前
|
JavaScript 前端开发 Java
JavaScript笔记(回顾一,基础知识篇)
JavaScript基础知识点回顾,包括语言定义、ECMAScript规范、字面量、变量声明、操作符、关键字、注释、流程控制语句、数据类型、类型转换和引用数据类型等。
JavaScript笔记(回顾一,基础知识篇)
|
1月前
|
存储 JavaScript 前端开发
前端开发:Vue.js入门与实战
【10月更文挑战第9天】前端开发:Vue.js入门与实战
|
22天前
|
前端开发 JavaScript
JavaScript新纪元:ES6+特性深度解析与实战应用
【10月更文挑战第29天】本文深入解析ES6+的核心特性,包括箭头函数、模板字符串、解构赋值、Promise、模块化和类等,结合实战应用,展示如何利用这些新特性编写更加高效和优雅的代码。
40 0
|
1月前
|
数据采集 JSON 前端开发
JavaScript逆向爬虫实战分析
JavaScript逆向爬虫实战分析