
有限状态机是一种数学模型,用于描述系统在不同状态之间转换的行为。在字符串解析的场景中,我们可以定义几个状态来表示解析器当前正在处理的文本类型:
通过在这些状态之间切换,并根据当前字符和当前状态执行不同的操作,我们可以精确地识别出独立的单词和完整的带引号短语。
下面我们将通过一个JavaScript函数 splitToWordsWithQuotes 来演示如何使用FSM思想实现字符串的智能分词。
function splitToWordsWithQuotes(str) {
let mode; // 当前解析模式:'word' (普通单词) 或 'phrase' (引号内短语)
const words = []; // 存储最终拆分出的单词和短语
let word = ''; // 临时缓冲区,用于累积当前正在解析的单词或短语
// 辅助函数:将当前累积的word添加到words数组中,并清空word缓冲区
const completeWord = () => {
if (word) { // 只有当word不为空时才添加
words.push(word);
word = '';
}
};
for (let i = 0; i < str.length; i++) {
const c = str[i]; // 当前字符
// 状态一:初始/空闲状态,尚未确定解析模式
if (!mode) {
if (c === ' ') {
continue; // 忽略开头的空格
}
if (c === '"') {
mode = 'phrase'; // 遇到双引号,进入短语模式
} else {
word += c; // 遇到非空格非引号字符,开始累积单词
mode = 'word'; // 进入单词模式
}
continue; // 处理下一个字符
}
// 状态二:已进入某种解析模式
// 遇到双引号
if (c === '"') {
completeWord(); // 结束当前单词或短语的累积
// 切换模式:如果当前是单词模式,遇到引号表示进入短语;反之,表示短语结束进入单词
mode = mode === 'word' ? 'phrase' : 'word';
continue; // 处理下一个字符
}
// 遇到空格
if (c === ' ') {
if (mode === 'phrase') {
word += ' '; // 在短语模式下,空格是短语的一部分,累积到word中
continue; // 处理下一个字符
}
// 在单词模式下,空格是分隔符
completeWord(); // 结束当前单词的累积
// 保持当前模式不变(或可以理解为回到空闲状态等待下一个非空格字符)
continue; // 处理下一个字符
}
// 遇到其他字符(字母、数字等)
word += c; // 累积到当前单词或短语中
}
// 循环结束后,确保将最后一个累积的word添加到words数组中
completeWord();
return words;
}代码解析要点:
让我们使用一些示例来验证这个解析器的功能:
立即学习“Java免费学习笔记(深入)”;
const myStr = ' "hello guys", some words with "quotes inside"" some spaces inside " please keep quoted words as one "phrase / word" end-of-line ';
const mySimpleStr = '"on time" "flight"';
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('原始字符串:', mySimpleStr);
console.log('解析结果:', splitToWordsWithQuotes(mySimpleStr));
// 预期输出: ["on time", "flight"]如上所示,splitToWordsWithQuotes 函数能够正确处理前导/尾随空格、多个空格分隔符,以及最关键的——将双引号内的短语作为一个整体进行识别和提取。
const myWrongStr = '"hello guys", some words" with "quotes inside" please keep quoted words as one "phrase / word" ';
console.log('\n--- 未闭合引号示例 ---');
console.log('原始字符串:', myWrongStr);
console.log('解析结果:', splitToWordsWithQuotes(myWrongStr));
// 结果可能不是你想要的,例如 "words" 会被拆分成 "words" 而不是 "words"
// 并且 "phrase / word" 后的引号没有关闭,会导致后续文本被错误解析const tokens = splitToWordsWithQuotes('"on time" "flight"'); // ["on time", "flight"]
const formattedOutput = tokens.map(token => {
if (token.includes(' ')) { // 简单判断是否为多词短语
return `"${token.toUpperCase()}"`;
}
return token.toUpperCase();
}).join(''); // 假设需要连接成一个字符串
console.log('\n--- 格式化示例 ---');
console.log('格式化后的输出:', formattedOutput); // ""ON TIME"FLIGHT"通过采用有限状态机的方法,我们可以构建一个健壮的JavaScript字符串解析器,有效地解决在复杂文本中区分普通单词和带引号短语的挑战。这种方法不仅提供了精确的分词能力,也为处理更复杂的字符串解析需求(如支持转义字符、处理不同类型的引号等)奠定了基础。理解并应用FSM模式,能够显著提升我们处理字符串数据的能力和代码的专业性。
以上就是JavaScript字符串解析:智能拆分单词并保留双引号短语的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号