2023-09-13 11:07:42
在 CodeMirror 中利用陵明正则表达式和 CSS 高亮日志字段,需结合正则匹配、DOM 操作和样式定义戚汪袜。以下是具体实现步骤:
1. 定义正则表达式匹配日志字段根据日志格式编写正则表达式,例如匹配 User [用户名] logged in 结构:
const regex = /User (w+) logged in/g; // w+ 匹配用户名(字母、数字、下划线)CodeMirror 提供了 getValue() 和 replaceRange() 等方法操作高激编辑器内容。若需动态高亮,需监听内容变化或手动触发高亮逻辑:
// 示例:获取编辑器内容并匹配const editor = CodeMirror.fromTextArea(document.getElementById('editor'), { mode: 'text/plain', // 根据日志类型选择模式(如 'javascript') lineNumbers: true});function highlightLogFields() { const logContent = editor.getValue(); const highlighted = logContent.replace(regex, `<span class="highlight">$&</span>`); // 注意:直接替换文本会破坏 CodeMirror 的结构,需通过标记(Marker)或装饰(Decoration)实现}CodeMirror 6 提供了 Decoration 和 WidgetType 实现无侵入式高亮:
import { basicSetup, EditorView } from "codemirror";import { javascript } from "@codemirror/lang-javascript";import { Decoration, ViewPlugin, WidgetType } from "@codemirror/view";class HighlightWidget extends WidgetType { constructor(readonly text) { super(); } eq(other) { return other.text === this.text; } toDOM() { const span = document.createElement("span"); span.className = "highlight"; span.textContent = this.text; return span; }}function highlightPlugin(view) { const text = view.state.doc.toString(); const matches = []; let match; while ((match = regex.exec(text)) !== null) { matches.push({ from: match.index, to: regex.lastIndex, text: match[0] // 匹配的完整文本 }); regex.lastIndex = match.index + 1; // 避免重叠匹配 } const decorations = Decoration.set( matches.map(match => Decoration.widget({ widget: new HighlightWidget(match.text), side: 0 }).range(match.from) ) ); return ViewPlugin.fromClass(class { decorations = decorations; update(update) { if (update.docChanged) { this.decorations = highlightPlugin(view).decorations; } } }, { decorations: v => v.decorations });}new EditorView({ doc: "User admin logged in at 2023-01-01nUser guest logged in", extensions: [basicSetup, javascript(), highlightPlugin], parent: document.body});自定义 WidgetType 包裹匹配文本并应用 CSS 类。
通过 ViewPlugin 动态更新装饰,响应内容变化。
在全局或编辑器容器中定义高亮样式:
.highlight { background-color: yellow; font-weight: bold; padding: 0 2px; border-radius: 2px;}CodeMirror 5 使用 lineWidgets 或 markText:editor.on("change", () => { const text = editor.getValue(); const matches = []; let match; while ((match = regex.exec(text)) !== null) { matches.push({ from: editor.posFromIndex(match.index), to: editor.posFromIndex(regex.lastIndex) }); regex.lastIndex = match.index + 1; } // 清除旧标记并添加新标记 editor.getAllMarks().forEach(mark => mark.clear()); matches.forEach(match => { editor.markText(match.from, match.to, { className: "highlight" }); });});
CodeMirror 6 推荐使用 Decoration(如上示例)。
通过上述方法,可实现动态、高效且可维护的日志字段高亮功能。