目前我有一个可编辑的div,我想添加非常基本的语法高亮显示。基本上我想要*之间的文字转换不同的颜色和引号中的文字以转换不同的颜色。例如:
输入:"hello" *world*
输出:<span class='a'>"hello"</span> <span class='b'>*world*</span>
我使用Rangy.js库来保存和恢复插入位置,因此那里没有问题。但是,我真的很难将输入转换为输出。我遇到的一个大问题是忽视任何&#34;和*已经突出显示。
如果有人能指出基本算法或正则表达式的方向,那么我将非常感激。
答案 0 :(得分:1)
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
包含以下内容:
[*"]
匹配*
或"
。 (它们不需要在[ ]
内转义。)( )
将匹配的字符串捕获到capture-group 1。.*?
匹配任何内容直到第一个...... \1
匹配捕获到捕获组1中的相同字符串。|
是“或”。它试图匹配左侧,如果失败,它会尝试匹配右侧。<[^<>]*>
匹配简单的html标记。它无法处理文字<
或>
中的属性:<a href="info.php?tag=<i>">
(无论如何这都是糟糕的HTML,但有些浏览器会接受它。)如果匹配HTML标记,ch
参数将为undefined
,并且else
- 分支将被选中。
如果要添加更多字符,只需将它们放在[ ]
中,然后添加if语句来处理它们。您可以使用除-
,\
和]
之外的任何字符,而无需转义它们。要添加这些字符,您需要在其前面放置另一个\
。
答案 1 :(得分:0)
您的基本算法是
function highlight(myInput) {
// Split the string into tokens.
// "[^"]*" matches a minimal run surrounded by quotes
// \*[^*]*\* matches a minimal run surrounded by asterisks
// ["*][^"*]* matches an unmatched quote or asterisk and the tail of the string
// [^"*]+ matches a maximal un-styled run
var tokens = myInput.match(/"[^"]*"|\*[^*]*\*|["*][^"*]*$|[^"*]+/g);
// Walk over the list of tokens and turn them into styled HTML
var htmlOut = [];
for (var i = 0, n = tokens.length; i < n; ++i) {
var token = tokens[i];
// Choose a style.
var className =
token.charAt(0) == '"' ? "a" : token.charAt(0) == '*' ? "b" : null;
// Surround in a span if we have a style.
if (className) { htmlOut.push("<span class='", className, "'>"); }
// HTML escape the token content.
htmlOut.push(token.replace(/&/g, "&").replace(/</g, "<"));
if (className) { htmlOut.push("</span>"); }
}
// Join the output tokens.
return htmlOut.join('');
}
alert(highlight('"hello" *world*'));