目前我有一个可编辑的 div,我想添加非常基本的语法突出显示。本质上,我希望 * 之间的文本变成不同的颜色,引号中的文本变成不同的颜色。例如:
输入:"hello" *world*
输出:<span class='a'>"hello"</span> <span class='b'>*world*</span>
我正在使用 Rangy.js 库来保存和恢复插入符位置,因此没有任何问题。然而,我真的很难将输入转化为输出。我遇到的大问题是忽略任何已经突出显示的“和*。
如果有人能给我指出基本算法或正则表达式或其他东西的方向,我将不胜感激。
最佳答案
function highlight(text) {
var result = [];
for (var i = 0; i < text.length; i++) {
if (text[i] === '"') {
var stop = text.indexOf('"', i + 1);
result.push('<span class="a">');
result.push(text.substring(i, stop+1));
result.push('</span>');
i = stop;
}
else if (text[i] === '*') {
var stop = text.indexOf('*', i + 1);
result.push('<span class="b">');
result.push(text.substring(i, stop+1));
result.push('</span>');
i = stop;
}
else if (text[i] === '<') {
// Skip simple HTML tags.
var stop = text.indexOf('>', i + 1);
result.push(text.substring(i, stop+1));
i = stop;
}
else {
result.push(text.substring(i,i+1));
}
}
return result.join('');
}
示例:
>>> highlight('foo *bar"baz"qux* "foobar" qux')
"foo <span class="b">*bar"baz"qux*</span> <span class="a">"foobar"</span> qux"
或者使用正则表达式:
function highlight2(text) {
return text.replace(/([*"]).*?\1|<[^<>]*>/g, function (match, ch) {
// 'match' contains the whole match
// 'ch' contains the first capture-group
if (ch === '"') {
return '<span class="a">' + match + '</span>';
}
else if (ch === '*') {
return '<span class="b">' + match + '</span>';
}
else {
return match;
}
});
}
正则表达式([*"]).*?\1
包含以下内容:
-
[*"]
匹配*
或"
。 (它们不需要在[ ]
内转义)。 -
( )
将匹配的字符串捕获到捕获组 1 中。 -
.*?
匹配任何内容,直到第一个... -
\1
与捕获组 1 中捕获的字符串匹配。 -
|
是“或”。它尝试匹配左侧,如果失败,它会尝试匹配右侧。 -
<[^<>]*>
匹配简单的 html 标签。它将无法处理带有文字<
的属性或>
其中:<a href="info.php?tag=<i>">
(无论如何,这都是糟糕的 HTML,但有些浏览器会接受它。)
当它与 HTML 标签匹配时,ch
参数将为 undefined
,以及else
-分支将被选择。
如果你想添加更多字符,只需将它们放在 [ ]
中即可,并添加一个 if 语句来处理它们。您可以使用除 -
之外的任何字符, \
和]
没有逃脱他们。要添加这些字符,您需要添加另一个 \
在他们面前。
关于javascript - 使用 javascript 进行简单语法高亮显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17280497/