- 桌面应用
【免费下载链接】QOwnNotes
QOwnNotes is a plain-text file notepad and todo-list manager with Markdown support and Nextcloud / ownCloud integration.
搜索是 QOwnNotes 日常使用中最核心的效率操作之一。本文基于 QOwnNotes 官方入门文档(webpage/src/nl/getting-started/searching.md)整理,并结合仓库源码(src/entities/note.cpp、src/managers/searchfiltermanager.cpp)深入讲解:如何通过快捷键快速调出"笔记搜索"面板、如何使用空格、引号以及n:/name:/w:/word:等搜索操作符组合出精确的查询,以及这些语法在底层是如何被解析与执行的。读完本文,你将能够像使用专业搜索工具一样在 QOwnNotes 中精准定位任何笔记。
在所有笔记中搜索
在当前笔记中搜索
一、快速调出搜索面板
在 QOwnNotes 中,无论是搜索笔记(按标题/文件名)还是搜索笔记正文中的文本,都可以使用快捷键:
- Linux / Windows:Ctrl+⇧ Shift+F
- macOS:⌘ Cmd+⇧ Shift+F
该快捷键会把焦点直接跳到界面左侧的笔记搜索(Note search)面板。从源码结构看,这个面板是一个QDockWidget,内嵌searchLineEdit输入框(见 src/mainwindow.cpp),快捷键触发的入口是MainWindow::on_action_Find_note_triggered()(见 src/mainwindow.cpp),最终由 src/managers/searchfiltermanager.cpp 中的SearchFilterManager统一完成过滤逻辑。
提示:搜索输入框从输入至少两个字符后才会开始过滤笔记(源码中
searchText.size() >= 2的判断见 src/managers/searchfiltermanager.cpp)。因此输入 1 个字符时不会触发搜索。
二、搜索语法总览
QOwnNotes 的搜索支持多种写法,下表覆盖了官方文档给出的全部核心语法:
| 输入示例 | 含义 |
|---|---|
note book | 在文件名或笔记正文中搜索同时包含note和book两个词的笔记(多词之间为 AND 关系) |
"notitieboek" | 搜索文件名或正文中精确包含短语notitieboek的笔记 |
n: boek或name: boek | 仅在笔记名称 / 文件名中搜索包含boek的笔记 |
n:"note book"或name:"note book" | 仅在笔记名称 / 文件名中精确匹配短语note book |
w:note或word:note | 把note作为完整单词搜索,不匹配notebook这类部分包含的情况 |
n:w:note | 组合操作符:仅在笔记名称 / 文件名中,把note作为完整单词搜索 |
1. 多词搜索:默认 AND 语义
直接输入多个词(用空格分隔),例如note book,会返回同时包含note和book的笔记,而不是"或"的关系。这一点在源码注释中有明确说明(见 src/entities/note.cpp):
"By default notes that contain every single word will be found,
word1 word2will find all notes that are containingword1andword2."
2. 引号:精确短语匹配
需要搜索包含完整短语的笔记时,给短语加上英文双引号,例如"this word1" word2——它会查找同时包含精确短语this word1和单词word2的笔记。底层实现中,带引号的内容会被单独解析为一个整体词条(见下文"解析器"一节)。
3. 名称限定:n:/name:
n:是name:的简写。该操作符把搜索范围限制在**笔记名称(note name)或文件名(file name)**内,不搜索正文。对应源码中的判断函数Note::isNameSearch()和前缀去除函数Note::removeNameSearchPrefix()(见 src/entities/note.cpp)。也可以与引号组合:n:"note book"。
4. 整词匹配:w:/word:
w:是word:的简写。默认搜索是子串匹配,即搜索note也会命中notebook;而使用w:note则要求note两侧必须是单词边界,notebook不会被命中。源码注释明确写道(见 src/entities/note.cpp):
"The
word:andw:operators match complete words instead of substrings."
5. 操作符可叠加组合
n:w:note表示"在笔记名称 / 文件名中,将note作为完整单词搜索",即同时满足名称限定与整词限定。底层解析器会循环剥离name:、word:、n:、w:前缀并分别设置nameOnly与wholeWord标志,因此多个操作符可以连续堆叠(见下文)。
三、源码级原理:搜索词是如何被解析与执行的
1. 搜索词解析器:buildSearchTermList
所有搜索输入最终都会被 Note::buildSearchTermList() 解析为一个QVector<NoteSearchTerm>。每个NoteSearchTerm结构体包含以下字段(定义见 src/entities/note.h):
struct NoteSearchTerm { QString text; // 实际搜索文本 QString namePrefix; // name: 或 n: 前缀 QString wordPrefix; // word: 或 w: 前缀 bool nameOnly = false; // 是否仅在名称中搜索 bool wholeWord = false; // 是否整词匹配 bool accentInsensitive = false; // 是否忽略拉丁字符重音 };解析过程分两步:
- 引号优先:先用正则
((?:(?:name:|word:|n:|w:))*)("([^"]+)")把带引号的内容(连同其前面的操作符前缀)整体捕获为一个词条,并从原字符串中移除; - 空格拆分:对剩余字符串按空格拆分,逐段解析。
对每个词条,解析器会循环匹配前缀正则^(name:|word:|n:|w:),遇到name:/n:就置nameOnly = true,遇到word:/w:就置wholeWord = true,然后剥离前缀继续匹配,这就是n:w:note这类多层组合得以实现的原因。另外,词条文本为空或原始长度小于 2 会被丢弃——这也解释了"至少输入两个字符才搜索"的限制。
2. 查询执行:SQLite LIKE 预筛 + Qt 精确校验
Note::searchInNotes()(见 src/entities/note.cpp)负责真正执行搜索。它采用"两阶段"策略:
- SQL 阶段:用 SQLite
LIKE在note表上预筛候选。普通词条匹配((note_text LIKE ? AND note_text NOT LIKE '%\n<加密标记>\n%') OR name LIKE ?),即同时搜索正文与名称;nameOnly词条则只匹配(name LIKE ? OR file_name LIKE ?)(见 src/entities/note.cpp)。值得注意的是,正文匹配会通过NOTE_TEXT_ENCRYPTION_PRE_STRING(<!-- BEGIN ENCRYPTED TEXT --,见 src/entities/note.h)排除加密笔记的密文内容,避免在加密文本里误命中。 - Qt 校验阶段:对于
wholeWord(整词)或accentInsensitive(忽略重音)的词条,SQLite 的LIKE无法胜任,因此会额外取出id, name, file_name, note_text列,在 Qt 侧用正则做二次校验。整词匹配的正则模式是\b+ 转义文本 +\b(见 src/entities/note.cpp),并开启CaseInsensitiveOption与UseUnicodePropertiesOption。
3. 忽略重音(拉丁字符)搜索
从源码看,搜索还支持"忽略拉丁字符重音"的特性:当设置项searchIgnoreAccents开启时(读取逻辑见 src/utils/misc.cpp),无重音词条会折叠重音后匹配,例如avion可以命中Avión。相关实现在 Utils::Misc::foldLatinAccents() 中,包含对ß→ss、æ→ae等特殊拉丁字符的手工折叠规则。
4. 结果排序
搜索到的笔记在列表中按file_last_modified DESC(最后修改时间倒序)排列,最新修改的笔记排在最前(见 src/entities/note.cpp)。
四、结果可视化与交互
1. 实时过滤与命中次数列
输入搜索词后,笔记树会实时过滤:不匹配的笔记被隐藏,匹配的笔记保留。如果启用了"显示匹配次数"(设置项showMatches),列表第二列会显示每个笔记中搜索词的命中次数(countSearchTextInNote()实现见 src/entities/note.cpp),鼠标悬停会弹出提示,例如"Found 5 occurrence(s) of note";多个词条时提示为"Found 5 occurrence(s) of any term of ..."(见 src/managers/searchfiltermanager.cpp)。
2. 当前笔记内搜索与高亮
除了在整个笔记库中过滤,QOwnNotes 还会把搜索词同步到当前打开笔记的搜索框(searchWidget)中,自动高亮所有命中并定位到第一处(见 src/managers/searchfiltermanager.cpp)。当搜索词是多个、整词或忽略重音时,会构造一个组合正则表达式并以正则模式搜索,确保高亮结果与笔记列表过滤一致(见 SearchFilterManager::doSearchInNote())。
3. 回车:跳转或新建笔记
在搜索框按Enter的行为值得单独说明(实现见 SearchFilterManager::jumpToNoteOrCreateNew()):
- 如果输入的文本恰好是某条笔记的名称(
Note::fetchByName(text)),则直接跳转到该笔记; - 如果没有找到,QOwnNotes 会以该文本为标题新建一条笔记,并通过
handleNewNoteHeadlineHook脚本钩子允许脚本定制初始正文,最后把当前选中的标签自动挂到新笔记上。
该行为同时会把本次搜索词存入"已保存的搜索"历史中(storeSavedSearch()),便于后续复用。
五、实践建议与小结
- 追求快:输入两个字符即开始过滤,配合 Ctrl/Cmd+Shift+F 全局快捷键,可以做到"想到即搜";
- 追求准:名称限定用
n:/name:,整词限定用w:/word:,精确短语用双引号,三者在n:"note book"、n:w:note中可自由组合; - 追求全:默认的"正文 + 名称"双字段子串搜索覆盖面最广,配合命中次数列可以快速评估每条结果的关联度;
- 遇到加密笔记:正文搜索会自动跳过加密密文段,仅当搜索词命中加密笔记的文件名/名称时才会出现在结果中,这一点可以从 src/entities/note.cpp 的实现中得到印证。
掌握这套语法与快捷键后,即使笔记库包含成千上万条纯文本笔记,也能在几秒内完成精准定位。本文涉及的搜索核心实现均可在仓库源码中进一步查阅:src/entities/note.cpp、src/entities/note.h、src/managers/searchfiltermanager.cpp 与 src/utils/misc.cpp。
- 桌面应用
【免费下载链接】QOwnNotes
QOwnNotes is a plain-text file notepad and todo-list manager with Markdown support and Nextcloud / ownCloud integration.
相关推荐
QOwnNotes 笔记搜索完全指南:搜索面板操作、语法操作符与源码实现解析
QOwnNotes 笔记搜索完全指南:搜索面板操作、语法操作符与源码实现解析 QOwnNotes 内置了一套强大而精细的笔记搜索体系:通过一个搜索面板,你可以在
桌面应用QOwnNotes 笔记搜索功能完全指南:搜索面板、语法算子与忽略变音符号
QOwnNotes 笔记搜索功能完全指南:搜索面板、语法算子与忽略变音符号 QOwnNotes 内置了基于本地 SQLite 索引的笔记搜索能力,通过快捷键一键
桌面应用QOwnNotes 笔记搜索完全指南:搜索面板、检索语法与忽略重音机制
QOwnNotes 笔记搜索完全指南:搜索面板、检索语法与忽略重音机制 导读 QOwnNotes 作为一款纯文本笔记与待办管理工具,内置了一套功能完整的笔记搜索
桌面应用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考