JavaScript 中基于状态机的文本分词与带引号短语处理教程

JavaScript 中基于状态机的文本分词与带引号短语处理教程

本教程详细阐述了如何在JavaScript中实现一个健壮的文本分词器,尤其侧重于正确处理包含空格的带引号短语。通过引入有限状态机(FSM)的概念,我们将学习如何逐字符解析字符串,区分普通单词和引号内短语,并将其作为独立单元提取,从而克服传统split()方法在复杂场景下的局限性。

引言:传统分词的局限性

javascript中,我们经常需要将一段文本拆分成独立的词语或短语。最常见的方法是使用string.prototype.split(‘ ‘)。然而,当遇到包含空格的带引号短语时,这种简单的方法便会失效。例如,对于输入字符串”on time” “flight”,我们期望将”on time”作为一个整体的短语,而”flight”作为一个单独的词。如果使用split(‘ ‘),”on time”会被错误地拆分成”on和time”`,这显然不符合我们的预期。

传统的split()方法无法区分引号内外的空格,导致无法正确识别带引号的短语。为了解决这一问题,我们需要一种更智能的解析策略,即有限状态机(Finite-State Machine, FSM)。

核心策略:有限状态机 (FSM) 分词

有限状态机是一种抽象的计算模型,它在任何给定时间点都处于有限数量的状态之一。根据输入事件,FSM会从一个状态转换到另一个状态。在文本分词场景中,我们可以定义不同的“状态”来表示解析器当前正在处理的文本类型(例如,普通单词或引号内的短语),并根据遇到的字符进行状态转换。

状态定义

为了实现带引号短语的正确分词,我们至少需要两种核心状态:

word 状态:表示解析器当前正在处理一个普通的单词,该单词不被双引号包围。phrase 状态:表示解析器当前正在处理一个被双引号包围的短语。在此状态下,空格应被视为短语的一部分,而不是分隔符。

状态转换逻辑

解析器会逐字符遍历输入字符串,并根据当前字符和当前所处的状态来决定:

立即学习“Java免费学习笔记(深入)”;

是否将当前字符添加到正在构建的词语/短语中。是否完成当前词语/短语并将其添加到结果列表中。是否从一个状态切换到另一个状态。

JavaScript 实现与代码解析

下面是一个使用FSM原理实现的JavaScript函数,用于将字符串拆分为单词和带引号的短语:

function splitToWordsWithQuotes(str) {    let mode = null; // null: 初始状态/空白区域, 'word': 正在构建单词, 'phrase': 正在构建短语    const words = []; // 存储最终分词结果的数组    let word = '';    // 临时变量,用于构建当前正在处理的词语或短语    // 辅助函数:完成当前词语/短语的构建,并将其添加到结果数组中    const completeWord = () => {        if (word.length > 0) { // 只有当word不为空时才添加            words.push(word);        }        word = ''; // 重置临时变量    };    for (let i = 0; i < str.length; i++) {        const c = str[i]; // 当前字符        if (mode === null) { // 初始状态或处于空白区域            if (c === ' ') {                continue; // 跳过空格            }            if (c === '"') {                mode = 'phrase'; // 遇到双引号,进入短语模式            } else {                word += c; // 遇到非空格非引号字符,开始构建单词                mode = 'word'; // 进入单词模式            }            continue;        }        if (c === '"') { // 遇到双引号            completeWord(); // 完成当前词语或短语            // 切换模式:如果当前是单词模式,则下一个是短语模式(尽管这通常意味着一个新词的开始,且这里没有处理转义引号)            // 如果当前是短语模式,则表示短语结束,回到等待新词的模式(null)            mode = null; // 遇到结束引号后,回到初始/空白状态,等待下一个词或短语            continue;        }        if (c === ' ') { // 遇到空格            if (mode === 'phrase') {                word += ' '; // 如果在短语模式,空格是短语的一部分                continue;            }            // 如果在单词模式,空格表示单词结束            completeWord();            mode = null; // 回到初始/空白状态            continue;        }        // 其他字符:添加到当前词语或短语中        word += c;    }    // 循环结束后,如果word中还有内容,需要完成最后的词语/短语    completeWord();    return words;}

代码解析:

mode 变量:这是状态机的核心。

null:表示当前解析器处于初始状态或正在跳过空格,等待新的词语或短语开始。’word’:表示正在收集一个普通单词的字符。’phrase’:表示正在收集一个带引号短语的字符。

words 数组和 word 变量

灵机语音 灵机语音

灵机语音

灵机语音 56 查看详情 灵机语音 words:存储所有已识别并完成的词语或短语。word:一个临时字符串,用于在当前状态下累积字符,直到一个词语或短语完成。

completeWord() 辅助函数:这个函数负责将当前word变量中的内容(如果非空)添加到words数组中,并清空word,为下一个词语或短语做准备。

字符遍历循环

初始/空白状态 (mode === null):遇到空格,直接跳过 (continue)。遇到双引号 (“),表示一个短语开始,将mode设置为’phrase’。遇到其他字符,表示一个普通单词开始,将字符添加到word,并将mode设置为’word’。遇到双引号 (c === ‘”‘):无论当前处于’word’还是’phrase’模式,遇到双引号都意味着当前词语/短语的结束。调用completeWord()。将mode重置为null,因为双引号通常是分隔符,之后需要重新判断下一个字符的类型。遇到空格 (c === ‘ ‘):如果在’phrase’模式,空格是短语的一部分,直接添加到word中。如果在’word’模式,空格表示当前单词结束。调用completeWord(),并将mode重置为null。其他字符:无论处于’word’还是’phrase’模式,其他字符(非空格、非双引号)都是当前词语或短语的一部分,直接添加到word中。

循环结束后的处理:循环结束后,word中可能还残留着最后一个词语或短语的字符,因此需要再次调用completeWord()来确保所有内容都被处理。

运行示例与结果分析

让我们使用一些示例输入来测试这个FSM分词器:

const myStr = '    "hello guys", some     words with "quotes inside"" some spaces inside " please keep quoted words as one "phrase / word" end-of-line ';const myWrongStr = '"hello guys", some words" with "quotes inside" please keep quoted words as one "phrase / word" ';console.log('--- 正常输入 ---');console.log('输入:', myStr);console.log('输出:', splitToWordsWithQuotes(myStr));// 预期输出: ["hello guys", "some", "words", "with", "quotes inside", "some", "spaces", "inside", "please keep quoted words as one", "phrase / word", "end-of-line"]console.log('n--- 包含未闭合引号的输入 ---');console.log('输入:', myWrongStr);console.log('输出:', splitToWordsWithQuotes(myWrongStr));// 预期输出: ["hello guys", "some", "words" with ", "quotes inside", "please keep quoted words as one", "phrase / word"]// 注意:未闭合的引号 "words" 被处理为 "words" with ",因为第二个引号被当作了短语的结束。

从示例中可以看出,splitToWordsWithQuotes 函数能够:

正确识别并提取带引号的短语,即使短语内部包含空格(如”hello guys”、”quotes inside”)。正确处理短语和单词之间的分隔(逗号、多个空格)。忽略字符串开头和结尾的空格。将普通单词正确地单独提取。

对于myWrongStr,它展示了当前FSM的一个特点:如果引号未正确闭合,它会继续将后续字符视为当前短语或单词的一部分,直到遇到下一个引号或分隔符。例如,some words” with 中的第二个引号被视为短语的结束,而不是一个未转义的引号字符。

注意事项与扩展

输出格式:当前FSM的输出是一个字符串数组,其中带引号的短语已经去除了原始的引号(例如,

以上就是JavaScript 中基于状态机的文本分词与带引号短语处理教程的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/211918.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月3日 13:08:32
下一篇 2025年11月3日 13:11:47

相关推荐

  • PHP中如何高效地标注长字符串中与目标字符串重复的语句?

    高效标注php长字符串中重复语句 本文探讨如何高效地在一个长字符串中标注与目标字符串重复的语句。 下图展示了问题的核心:如何处理长字符串与目标字符串的比对。 现有方法通常采用循环和mb_substr函数将长字符串分割成多个子字符串,再逐一与目标字符串进行比较。这种方法效率低下,尤其当字符串长度较长时…

    2025年12月11日
    000
  • PHP字符串与数组对比:如何高效高亮显示长字符串中重复的子字符串?

    高效高亮显示长字符串中重复子字符串的php方法 本文介绍一种高效的方法,用于高亮显示长字符串中重复出现的子字符串。 假设我们有一个长字符串$aa和一个较短的字符串$str,目标是找到$str在$aa中所有出现的位置,并将其用HTML标签高亮显示。 传统方法通常需要循环遍历和比较,效率较低。 本文采用…

    2025年12月11日
    000
  • 使用phpMyAdmin快速创建和管理数据库表

    phpmyadmin是一个基于web的mysql数据库管理工具,它提供图形界面,简化数据库操作。使用它创建数据库表的方法是:1. 选择数据库;2. 点击“新建”按钮;3. 定义表名、字段名、数据类型和长度等;4. 点击“保存”。phpmyadmin将操作转换成sql语句执行,同时支持数据导入导出和表…

    2025年12月11日
    000
  • 在 Mac 上安装 PHP 指南

    PHP 是一种广泛使用的 Web 开发编程语言,可以按照以下步骤将 PHP 安装在您的 Mac 上 1.安装 Homebrew:使用适用于 macOS 的包管理器 Homebrew。打开终端应用程序并运行命令: /bin/bash -c “$(curl -fsSL https://raw.githu…

    2025年12月11日
    000
  • PHP字符串处理:如何高效去除特定长度的子字符串?

    php去除字符串中特定长度部分 在处理字符串时,去除特定长度的部分是一个常见需求。本问答将探讨如何使用 php 快速处理此任务。 给定字符串:1,22,333,啊,啊啊,啊啊啊,4444 任务:去除字符串中长度小于或等于 2 和大于或等于 3 的部分 立即学习“PHP免费学习笔记(深入)”; 问题:…

    2025年12月10日
    000
  • PHP函数代码风格的在线资源

    PHP 函数代码风格的在线资源 保持一致的代码风格对于代码可读性和可维护性至关重要。对于 PHP,有一些在线资源可以帮助您遵守最佳实践。 PHP_CodeSniffer PHP_CodeSniffer 是一款静态分析工具,可根据一组预定义的规则检查 PHP 代码。它可以检测编码标准违规并建议修复。您…

    2025年12月10日
    000
  • php函数跨语言调用实战指导

    #%#$#%@%@%$#%$#%#%#$%@_e1bfd762321e409c++ee4ac0b6e841963c 可通过外部函数接口(ffi)实现与其他语言的跨语言调用。实战案例:安装 ffi 扩展定义 c++ 函数签名加载 c++ 函数库使用 ffi 库调用 c++ 函数,实现从 php 调用其…

    2025年12月10日
    000
  • 使用linter工具实现PHP函数参数类型检查

    通过使用linter工具phpstan,我们可以实现php函数参数的类型检查。phpstan是一种静态分析工具,可通过分析变量类型的推断来检查函数参数类型。我们可以使用composer安装phpstan并通过配置phpstan.neon文件来设置检查级别。phpstan通过类型断言和严格类型检查来检…

    2025年12月10日
    000
  • 币圈十大看行情软件推荐 币圈十大交易所最新排名2025

    在瞬息万变的数字资产领域,选择一个可靠且功能强大的行情分析软件至关重要。这些工具不仅帮助投资者追踪市场动态,更提供了深入分析和交易决策的依据。本文将为您盘点2025年币圈十大行情软件及交易所最新排名,助力您在数字货币的海洋中乘风破浪。 币圈十大行情软件推荐及交易所最新排名2025 1. Binanc…

    2025年12月10日 好文分享
    000
  • 2025年狗狗币Dogecoin价格即将暴涨?揭秘黄金十字背后的三大爆发信号!

    Binance币安 %ignore_a_2%OKX ️ Huobi火币️ 狗狗币(DOGE)在2025年下半年确实展现出强劲的技术信号和市场动能,价格是否即将暴涨,关键在于多重因素的共振。从技术形态到链上活动,再到潜在的政策催化,已有三大爆发信号浮现,值得投资者重点关注。 黄金交叉确认,技术面进入看…

    2025年12月10日
    000
  • 狗狗币 Dogecoin(狗狗币)今日价格行情 狗狗币(DOGE/USDT)行情

    Binance币安 欧易OKX ️ Huobi火币️ 根据2025年10月13日的最新数据,狗狗币(Dogecoin)的价格约为  0.20763,24小时内上涨了11.780.20763,24小时内上涨了11.78  314.6亿。 价格走势 24小时波动:价格在0.18480至0.18480至 …

    2025年12月10日
    000
  • 如何评估加密货币的价值?

    评估加密货币价值需结合基本面、技术分析与风险管理。首先,将代币视为“数字主权国家”,从经济(代币机制、链上数据)、公民(社区共识)、基础设施(dApp生态)三方面评估其内在价值;其次,针对不同资产类型采用相应模型:公链适用梅特卡夫定律,CEX平台币关注交易量增长与销毁率,DeFi项目尝试现金流贴现;…

    2025年12月10日
    000
  • 2025年BTC价格预测:技术面与基本面双重利好,目标价15万美元

    BTC技术面分析:突破关键阻力位 BTC价格走势呈现强劲上升趋势 根据最新行情数据,比特币(BTC)在2025年10月上旬强势突破12.4万美元关口,并一度触及125,689美元的历史新高。截至近期交易日,BTC/USDT报价稳定在124,800美元上方,显著高于20日均线116,355.80美元,…

    2025年12月10日
    000
  • BNB币2025年价格预测:突破历史新高后,BNB会达到$2,000吗?

    目录 BNB Chain 及其原生代币BNB 的代币经济学是什么?BNB 的主要用途包括:是什么推动BNB 在2025 年10 月创下历史新高?1. 链上活动激增,推动BNB 代币销毁创纪录2. 机构采用将BNB 确立为企业储备资产3. BNB Chain 生态系统增长巩固长期基础4. 市场动能和恢…

    2025年12月10日 好文分享
    000
  • 比特币十月将涨破14万?胜率高达8成的Uptopber介绍

    目录 Uptober是什么?加密货币市场的超级幸运月过往比特币十月的表现:十年来Uptober 的涨势数据2025年Uptober开局:突破116,000大关2025年Uptober潜在目标价:或许有望挑战14万今年Uptober会不会成真:从总经、技术和情绪面观察笔者观点 在加密货币市场中,时局一…

    2025年12月10日
    100
  • Bybit:衍生品专家

    Bybit 是衍生品交易领域的专家,凭借专注性、高性能交易系统和严格风控体系构建核心竞争力。其提供永续合约、交割合约和期权等丰富产品,支持高杠杆、低延迟交易,并通过智能清算、保险基金和ADL机制保障安全。平台具备统一保证金账户、API 接口、多语言客服及教育资源,提升用户体验。同时强调风险管理,建议…

    2025年12月10日
    000
  • 一文详细了解SharpLink的以太坊(ETH)持仓未实现收益接近10亿美元

    目录 SharpLink持有近83.9万枚ETH 以太坊财库公司与ETF合计掌控超10%的ETH流通量 目前,专注于以太坊的企业财库和交易所交易基金(ETF)所持有的ETH总量已突破总供应量的10%,其中SharpLink与BitMine成为企业级持仓的领头羊。 随着以太坊价格在最近24小时内上涨约…

    2025年12月10日
    000
  • Plasma(XPL)币价格预测2025-2030年 : XPL币能否复制 Tether 的增长路径?

    目录  Plasma (XPL) 是什么?如何运作?XPL 代币有什么用途?Plasma (XPL) 代币经济学概览Plasma (XPL) 的风险和挑战零费用模式的可持续性监管风险竞争格局技术安全风险Plasma (XPL) 的前景2025-2030年等离子(XPL)价格预测等离子(XPL)202…

    2025年12月10日
    000
  • Bitfinex:专业交易

    在加密货币交易的浩瀚宇宙中,bitfinex无疑是其中一颗耀眼的星辰。它不仅仅是一个简单的交易所,更是一个为专业交易者量身定制的复杂生态系统。踏入bitfinex的大门,你将发现一个集高流动性、先进交易工具、深度市场数据以及强大安全保障于一体的交易殿堂。这里汇聚了全球顶级的机构投资者、资深交易员以及…

    好文分享 2025年12月10日
    000
  • Curve(CRV)币2025年价格预测:CRV代币最新走势、未来潜力介绍

    目录 什么是 Curve DAO 代币 (CRV)?Curve(CRV)的历史表现市场现状:当前加密货币环境概览Curve 技术分析:关键水平与可能走势03 影响 Curve 价格的基本面因素Curve 价格预测:短期与长期展望短期展望(2025 年第四季度)中期展望(2026 年)投资策略与风险提…

    2025年12月10日
    000

发表回复

登录后才能评论
关注微信