這是對 SQL 實現語法高亮的部分:javascript
//可用的語法着色數據 var Colors = { //Sql 暗 SqlDark: { "language": "Sql", "theme": "dark", "objectColor": "#8BC96C", "operatorColor": "#A7A7A7", "annotationColor": "#3E983E", "annotationsColor": "#3E983E", "stringColor": "#FF9393", "constantColor": "#B5CEA8", "keywordsInfo": [{ "color": "#7C9DED", "keywords": ["USE", "GO", "SET", "ANSI_NULLS", "OFF", "ALTER", "TABLE", "UPDATE", "ORDER", "BY", "DESC", "ASC", "PROCEDURE", "QUOTED_IDENTIFIER", "IDENTITY_INSERT", "OUTPUT", "INT", "BIGINT", "NCHAR", "VARCHAR", "NTEXT", "VARBINARY", "BINARY", "SYSNAME", "AS", "NOCOUNT", "ON", "DECLARE", "IF", "ELSE", "BEGIN", "END", "WHILE", "CASE", "WHEN", "THEN", "RAISERROR", "RETURN", "SELECT", "TOP", "DELETE", "EXEC", "FROM", "WHERE", "TRAN", "SAVE", "INSERT", "INTO", "VALUES", "TYPE", "GOTO", "COMMIT", "UNDO:", "ROLLBACK", "TRANSACTION", "NVARCHAR", "SYSNAME", "UNIQUEIDENTIFIER", "BIT", "TINYINT", "DATETIME", "MASTER", "VERSION", "EXECUTE", "DBCC", "SYSTEM", "PRINT"] }, { "color": "#A7A7A7", "keywords": ["NULL", "AND", "IS", "OR", "NOT", "IN", "EXISTS", "BETWEEN", "LEFT", "RIGHT", "JOIN"] }, { "color": "#C940C9", "keywords": ["COLLATE"] }], "functionsInfo": [{ "color": "#C940C9", "keywords": ["CONVERT", "ISNULL", "IS_SRVROLEMEMBER", "ROW_NUMBER", "MAX", "MIN", "COUNT", "UPPER", "LOWER", "SUBSTRING", "REPLACE", "LEN", "IDENT_CURRENT", "QUOTENAME", "RTRIM", "LTRIM", "SUM", "DB_ID", "DB_NAME", "CAST", "PLATFORM", "SERVERPROPERTY", "NEWID", "DATALENGTH", "OBJECT_ID"] }] } }; //使用某一種顏色數據對指定的文本進行語法着色(主入口) function StainColor(text, colorObj) { if (colorObj.language == "Sql") { return StainGrammerSql(text, colorObj); } } //Sql 語法着色 function StainGrammerSql(text, colorObj) { text = text.replace(/&/g, "&"); text = text.replace(/\</g, "<").replace(/\>/g, ">"); var t_regex = null; //暫時排除單引號形式的字符串 var chars = new Array(); var tchar = null; while (tchar = text.match(/N?'(?:(?:'')|[^'\r\n]|)*'/)) { text = text.replace(/N?'(?:(?:'')|[^'\r\n]|)*'/, "###char_{" + chars.length + "}###"); chars.push(tchar[0]); } //暫時排除多行註釋 var comments = new Array(); var tcomment = null; while (tcomment = text.match(/\/\*(?:.|\s)*?\*\//)) { text = text.replace(/\/\*(?:.|\s)*?\*\//, "###comment_{" + comments.length + "}###"); comments.push(tcomment[0]); } //暫時排除單行註釋 var annotations = new Array(); var tannotation = null; while (tannotation = text.match(/\-\-.*/)) { text = text.replace(/\-\-.*/, "###annotation_{" + annotations.length + "}###"); annotations.push(tannotation[0]); } //暫時排除標量變量 var vars = new Array(); var tvar = null; while (tvar = text.match(/@[\d\w$#@]*/)) { text = text.replace(/@[\d\w$#@]*/, "###var_{" + vars.length + "}###"); vars.push(tvar[0]); } //暫時排除運算符 var operators = new Array(); var toperator = null; while (toperator = text.match(/(?:<)|(?:>)|(?:&)|[\(\),=\+\-\*\/!&~\.%]/)) { text = text.replace(/(?:<)|(?:>)|(?:&)|[\(\),=\+\-\*\/!&~\.%]/, "###operator_{" + operators.length + "}###"); operators.push(toperator[0]); } //暫時排除常數 var constants = new Array(); var tconstant = null; while (tconstant = text.match(/\b\d+(?!\}#)\b/)) { text = text.replace(/\b\d+(?!\}#)\b/, "###constant_{" + constants.length + "}###"); constants.push(tconstant[0]); } //暫時排除對象標識符 var objects = new Array(); while (text.indexOf("[") >= 0) { var charStart = pCrt = text.indexOf("["); var cCrt = ''; while (cCrt = text[pCrt]) { if (cCrt == "[") { charStart = pCrt; } else if (cCrt == "]") { var center = text.substring(charStart, pCrt + 1); var left = text.substr(0, charStart); var right = text.substr(pCrt + 1); var replaced = "###object_{" + objects.length + "}###"; objects.push(center); text = left + replaced + right; break; } pCrt += 1; } } //關鍵字着色 for (var i = 0; i < colorObj.keywordsInfo.length; i++) { for (var j = 0; j < colorObj.keywordsInfo[i].keywords.length; j++) { t_regex = new RegExp("\\b" + colorObj.keywordsInfo[i].keywords[j] + "\\b", "gi"); var coloredText = "<strong style=\"color:" + colorObj.keywordsInfo[i].color + ";\">" + colorObj.keywordsInfo[i].keywords[j] + "</strong>"; text = text.replace(t_regex, coloredText); } } //函數着色 for (var i = 0; i < colorObj.functionsInfo.length; i++) { for (var j = 0; j < colorObj.functionsInfo[i].keywords.length; j++) { t_regex = new RegExp(colorObj.functionsInfo[i].keywords[j] + "(?= *###operator_)", "gi"); var coloredText = "<strong style=\"color:" + colorObj.functionsInfo[i].color + ";\">" + colorObj.functionsInfo[i].keywords[j] + "</strong>"; text = text.replace(t_regex, coloredText); } } //還原並着色對象標識符 for (var i = 0; i < objects.length; i++) { var coloredText = "<strong style=\"color:" + colorObj.objectColor + ";\">" + objects[i] + "</strong>"; t_regex = new RegExp("###object_\\{" + i + "\\}###"); text = text.replace(t_regex, coloredText); } //還原並着色常數 for (var i = 0; i < constants.length; i++) { var coloredText = "<strong style=\"color:" + colorObj.constantColor + ";\">" + constants[i] + "</strong>"; t_regex = new RegExp("###constant_\\{" + i + "\\}###"); text = text.replace(t_regex, coloredText); } //還原並着色運算符 for (var i = 0; i < operators.length; i++) { var coloredText = "<strong style=\"color:" + colorObj.operatorColor + ";\">" + operators[i] + "</strong>"; t_regex = new RegExp("###operator_\\{" + i + "\\}###"); text = text.replace(t_regex, coloredText); } //還原並着色標量變量 for (var i = 0; i < vars.length; i++) { var coloredText = "<strong style=\"color:" + colorObj.objectColor + ";\">" + vars[i] + "</strong>"; t_regex = new RegExp("###var_\\{" + i + "\\}###"); text = text.replace(t_regex, coloredText); } //還原並着色非空單引號形式的字符串 for (var i = 0; i < chars.length; i++) { var coloredText = "<strong style=\"color:" + colorObj.stringColor + ";\">" + chars[i] + "</strong>"; t_regex = new RegExp("###char_\\{" + i + "\\}###"); text = text.replace(t_regex, coloredText); } //還原並着色單行註釋 for (var i = 0; i < annotations.length; i++) { //還原單行註釋中單引號形式的字符串 var t_char = null; while (t_char = annotations[i].match(/###char_\{(\d+)\}###/)) { annotations[i] = annotations[i].replace(/###char_\{(\d+)\}###/, chars[t_char[1]]); } //還原單行註釋中的多行註釋 var t_comment = null; while (t_comment = annotations[i].match(/###comment_\{(\d+)\}###/)) { annotations[i] = annotations[i].replace(/###comment_\{(\d+)\}###/, comments[t_comment[1]]); } var coloredText = "<strong style=\"color:" + colorObj.annotationColor + ";\">" + annotations[i] + "</strong>"; t_regex = new RegExp("###annotation_\\{" + i + "\\}###"); text = text.replace(t_regex, coloredText); } //還原並着色多行註釋 for (var i = 0; i < comments.length; i++) { //還原註釋中單引號形式的字符串 var t_char = null; while (t_char = comments[i].match(/###char_\{(\d+)\}###/)) { comments[i] = comments[i].replace(/###char_\{(\d+)\}###/, chars[t_char[1]]); } var coloredText = "<strong style=\"color:" + colorObj.annotationsColor + ";\">" + comments[i] + "</strong>"; t_regex = new RegExp("###comment_\\{" + i + "\\}###"); text = text.replace(t_regex, coloredText); } return text; }
SQL 的高亮相對來說並非很複雜,由於大小寫不敏感和語法不夠嚴謹的關係,這裏主要是採起的關鍵字高亮的方法,只是用到了不一樣顏色的關鍵字,效果以下圖:java