精华帖 (7) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-09-03
javascript中大括号的多义性,注定使用正则进行分析是不现实的
如果追求的是“好用”、“简小”,那么正则无疑是一个好工具,完成80%以上的需求而不会引入太大的复杂度 但如果追求“准确率之最”,恐怕正则是顶不住的 所以我个人不建议楼主以“准确率之最”这样的词进行宣传和推广,一个高亮功能需要的不仅仅是准确率,还有很多其他的路可以走…… |
|
返回顶楼 | |
发表时间:2011-09-04
支持楼主,赞,
|
|
返回顶楼 | |
发表时间:2011-09-04
最后修改:2011-09-04
前一阵也写过一个这方面的代码加亮,但只实现了JS部分,没有实现html和CSS部分。
我的代码只是楼主实现的功能的一个子集,但优点是简单,对于不太复杂、比较规矩 的代码,没有问题,加亮mootools.js、JQuery等类库几乎和我的notepad++上的效果是 一样的。楼主的程序的分析功能做的很好,有些很坑爹的句式都能正确处理,我的代码 处理不了。 <!doctype html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>color keywords </title> <style type="text/css"> * { font-family: "新宋体"; } #txtCode{ width : 100%; height: 200px; resize: vertical; } b.Comments{ color:#159AE0; font-weight:500; } b.String{ color:#27A735; font-weight:500; } b.RegExp{ color:#EA842B; font-weight:500; } b.Keywords{ color:#FFAA00; font-weight:500; } b.Number{ color:#9C3583; font-weight:500; } b.Operator{ color:#FFAA00; font-weight:500; } b.LineNo{ background-color : #2e3436; margin-right : 5px; color : #8CBBAD; font-weight : 500; } .Output{ border : 1px solid #396; color : white; resize : both; font-size : 16px; width : 100%; word-wrap : no-wrap; /*使不自动换行, 调试中*/ word-break : keep-all; background-color: #0B161D; } </style> <script type="text/javascript"> function colorKeywords(){ var source = $("txtCode").value; if( source == "" ) return; var ds = new Date(); var keywords = "Array|arguments|alert|window|document|location|Boolean|Date|Enumerator|Error|Function|Global|Math|Number|Object|RegExp|String|break|delete|function|return|typeof|case|do|if|switch|var|catch|else|in|this|void|continue|false|instanceof|throw|while|debugger|finally|new|true|with|default|for|null|try|abstract|double|goto|native|static|boolean|enum|implements|package|super|byte|export|import|private|synchronized|char|extends|int|protected|print|throws|class|final|interface|public|transient|const|float|long|short|volatile"; var operators = "\\+\\+|--|===|==|\\+=|-=|\\*=|%=|~=|\\^=|&=|>=|<=|>|<|!=|!|\\|=|\\+|-|\\*|%|=|\\?|\\:|\\{|\\}|\\(|\\)|\\[|\\]|&&|&|\\|\\||\\|"; //解析优先级: 注释 > 字符串 > 正则 > 关键字 > 数字 > 运算符 > \s\n\t等占位符 var regStr = ( "(/\\*[\\S\\s]*?\\*/|//.*?\\r?\\n)" + "|((?:\"(?:[^\"]*?\\\\\")*.*?\")|(?:'(?:[^']*?\\\\')*.*?'))" + "|(/(?:[^/]+?\\\\/)*.*?/[a-zA-Z]*)" + "|(\\b(?:"+keywords+")\\b)" + "|(\\b\\d+\\b)" + "|("+ operators +")" //不需要的话可以去掉此行 + "|((?:\\r?\\n)|\\s|\\t)" //注意\s会匹配换行符\n, 因此换行符的匹配需要提前 ); var parseReg= new RegExp(regStr, "g"); //格式化数字函数 var formatNo = function(n){ if( n < 10 ){ return " " + n; }else if(n < 100 ){ return " " + n; }else if(n < 1000){ return " " + n; }else if(n < 10000){ return " " + n; }else{ return n; } }; //处理字符串中的特殊字符,并在需要换行的时候添加行号 var lineNo = 1; var handleStr = function(str){ return str.replace(/<|>|&|\r?\n|\s|\t/g, function(match){ switch( match ){ case "<" : return "<" ; case ">" : return ">" ; case "&" : return "&" ; case " " : return " " ; case "\t" : return " "; case "\n" : case "\r\n" : return "<br/><b class='LineNo'>" + formatNo(++lineNo) + ".</b>"; } }); }; //对关键字进行着色 var output = source.replace(parseReg, function(){ var args = arguments, lstIdx = args[args.length - 2], match = args[0], preChar = lstIdx > 0 ? source.charAt(lstIdx-1) : ""; if (args[1]) return "<b class='Comments'>" + handleStr(match) + "</b>"; if (args[2]) return "<b class='String' >" + handleStr(match) + "</b>"; if (args[3]) return "<b class='RegExp' >" + handleStr(match) + "</b>"; if (args[4]) return (preChar != "$") ? "<b class='Keywords'>"+ match + "</b>" : match; if (args[5]) return (preChar != "$") ? "<b class='Number'>" + match + "</b>" : match; if (args[6]) return "<b class='Operator'>" + handleStr(match) + "</b>"; if (args[7]) return handleStr(match); return match; }); output = "<b class='LineNo'>" + formatNo(1) + ".</b>" + output; //计算耗时 var de = new Date(); alert("处理字符串耗时:" + (de - ds)); //输出格式化后的内容 $("output").innerHTML = output; } //辅助代码--------------------------------------- function $(id){ return document.getElementById(id); } function clearOutput(){ $("output").innerHTML=""; } </script> </head> <body> <input type="button" value="代码着色" onClick="colorKeywords()" /> <input type="button" value="清空输出" onClick="clearOutput()" /> <br/> <br/> 请输入要着色的代码: <textarea id="txtCode"> /**--------------------------- * test multiline comments * @author jianbo.wang */ function(){ //测试单行注释着色 /**-------------------------- * 测试多行注释着色. *--------------------------*/ //测试字符串着色. print("\"hello world!\""); print('will output:"hello world!"'); //测试正则着色 var reg = /(<\/?\w+.*?>)|(\s)/g; //测试关键字着色 var output, _window, $window, c= window.alert, d= $window.alert, e= _window.alert, f= window._alert, g= $window._alert, h= _widnow._alert i= window.$alert, j= $window.$alert, k= _window.$alert; for(var i=0; i <100; i++){ output = "Welcome user" + i; alert(output); } //测试数字着色 var $1, $2, _1, _2, a = 100, b= "200", $100, _200, c="$200", d="_100"; //运算符着色测试 var index = 0; var user = { name : "张三", age : 12, index: index++ }; var a = 0; a++; a--; a+="hello"; a+=100; a-=1; a*=1; a%=1; a>=1; a <=1; a > b; a != 2; (a === 1 ) ? true : false; (a == 1 ) ? true : false; (a = 1 ) ? true : false; (a > 1 ) ? true : false; if( a > 1 || a < 0 || (a == "string" && b == "number" ) return false; } //测试输出渲染函数 function colorKeywords(){ var source = $("txtCode").value; if( source == "" ) return; var ds = new Date(); var keywords = "Array|arguments|alert|window|document|location|Boolean|Date|Enumerator|Error|Function|Global|Math|Number|Object|RegExp|String|break|delete|function|return|typeof|case|do|if|switch|var|catch|else|in|this|void|continue|false|instanceof|throw|while|debugger|finally|new|true|with|default|for|null|try|abstract|double|goto|native|static|boolean|enum|implements|package|super|byte|export|import|private|synchronized|char|extends|int|protected|print|throws|class|final|interface|public|transient|const|float|long|short|volatile"; var operators = "\\+\\+|--|===|==|\\+=|-=|\\*=|%=|~=|\\^=|&=|>=| <=|>| <|!=|!|\\|=|\\+|-|\\*|%|=|\\?|\\:|\\{|\\}|\\(|\\)|\\[|\\]|&&|&|\\|\\||\\|"; //解析优先级: 注释 > 字符串 > 正则 > 关键字 > 数字 > 运算符 > \s\n\t等占位符 var regStr = ( "(/\\*[\\S\\s]*?\\*/|//.*?\\r?\\n)" + "|((?:\"(?:[^\"]*?\\\\\")*.*?\")|(?:'(?:[^']*?\\\\')*.*?'))" + "|(/(?:[^/]+?\\\\/)*.*?/[a-zA-Z]*)" + "|(\\b(?:"+keywords+")\\b)" + "|(\\b\\d+\\b)" + "|("+ operators +")" //不需要的话可以去掉此行 + "|((?:\\r?\\n)|\\s|\\t)" //注意\s会匹配换行符\n, 因此换行符的匹配需要提前 ); var parseReg= new RegExp(regStr, "g"); //格式化数字函数 var formatNo = function(n){ if( n < 10 ){ return " " + n; }else if( n < 100 ){ return " " + n; }else if( n < 1000){ return " " + n; }else if( n < 10000){ return " " + n; }else{ return n; } }; //处理字符串中的特殊字符,并在需要换行的时候添加行号 var lineNo = 1; var handleStr = function(source){ return source.replace(/<|>|&|\s|\t|\r?\n/g, function(match){ switch( match ){ case "<" : return "&lt;" ; case ">" : return "&gt;" ; case "&" : return "&amp;" ; case " " : return "&nbsp;" ; case "\t" : return "&nbsp;&nbsp;&nbsp;&nbsp;"; case "\n" : case "\r\n" : return "<br/><b class='LineNo'>" + formatNo(++lineNo) + ".</b>"; } }); }; //对关键字进行着色 var output = source.replace(parseReg, function(){ var args = arguments; var lstIdx = args[args.length - 2]; var match = args[0]; var preChar = lstIdx > 0 ? source.charAt(lstIdx-1) : ""; if( args[1] ) return "<b class='Comments'>" + handleStr(match) + "</b>"; if( args[2] ) return "<b class='String' >" + handleStr(match) + "</b>"; if( args[3] ) return "<b class='RegExp' >" + handleStr(match) + "</b>"; if( args[4] ) return (preChar != "$") ? "<b class='Keywords'>"+ match + "</b>" : match; if( args[5] ) return (preChar != "$") ? "<b class='Number'>" + match + "</b>" : match; if( args[6] ) return "<b class='Operator'>" + handleStr(match) + "</b>"; if( args[7] ) return handleStr(match); return match; }); output = "<b class='LineNo'>" + formatNo(1) + ".</b>" + output; //计算耗时 var de = new Date(); alert("处理字符串耗时:" + (de - ds)); //输出格式化后的内容 $("output").innerHTML = output; } function $(id){ return document.getElementById(id); } function clearOutput(){ $("output").innerHTML=""; } </textarea> <br/> <br/> 代码着色结果: <div id="output" class="Output" > codes output here! </div> </body> </html> |
|
返回顶楼 | |
发表时间:2011-09-05
确实非常不错的一个JS库,学习了,谢谢分享。
|
|
返回顶楼 | |
发表时间:2011-09-05
楼主可以参考的看一下ace项目。google group上貌似就有Ace的项目。已经实现了js高亮显示。感觉那个很棒~
|
|
返回顶楼 | |
发表时间:2011-09-05
int08h 写道 javascript中大括号的多义性,注定使用正则进行分析是不现实的
如果追求的是“好用”、“简小”,那么正则无疑是一个好工具,完成80%以上的需求而不会引入太大的复杂度 但如果追求“准确率之最”,恐怕正则是顶不住的 所以我个人不建议楼主以“准确率之最”这样的词进行宣传和推广,一个高亮功能需要的不仅仅是准确率,还有很多其他的路可以走…… 谢谢建议,其实看网上很多有名的加亮对正则处理的不好,所以就处理了下正则,有点纠结了,某些正则确实无需那么准确,现在是以牺牲一定性能来达到准确性的,不过这里的执行功能不知道大家看见没有,不知道这个功能需求怎么样! 就像51js那样,一段html或者js可以被执行! |
|
返回顶楼 | |
发表时间:2011-09-05
最后修改:2011-09-05
xingqiliudehuanghun 写道
前一阵也写过一个这方面的代码加亮,但只实现了JS部分,没有实现html和CSS部分。
我的代码只是楼主实现的功能的一个子集,但优点是简单,对于不太复杂、比较规矩 的代码,没有问题,加亮mootools.js、JQuery等类库几乎和我的notepad++上的效果是 一样的。楼主的程序的分析功能做的很好,有些很坑爹的句式都能正确处理,我的代码 处理不了。
|
|
返回顶楼 | |
发表时间:2011-09-05
31212 写道
楼主可以参考的看一下ace项目。google group上貌似就有Ace的项目。已经实现了js高亮显示。感觉那个很棒~
能给个地址吗?居然没搜索到!学习学习,呵呵! |
|
返回顶楼 | |
发表时间:2011-09-06
JS中的正则真是个麻烦的问题, 如果想做的精度比较高的话,估计用正则就不行了,可能需要想解析器一样,逐个字符进行分析。
|
|
返回顶楼 | |
发表时间:2011-09-06
黑底的配色 比较帅
|
|
返回顶楼 | |