




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、js 玩转正则表达式之语法高亮学了几天正则,差不多该总结整理写成果了,通过分析2位大神的代码,整理出来的一篇很实用的文章学了几天正则,差不多该总结整理写成果了,之前就想写语法高亮匹配来着,不过水平不够,看着例子都不理解。 那么我们来分析下两位大神 次碳酸钴 和 Barret Lee 语法高亮实现。 先说 Barret Lee 的这篇 几个小例子教你如何实现正则表达式highlight高亮 之前看的时候只觉的神奇,特别是下面那个一步一步分开匹配的例子,更是霸气测漏,不过作者也说了,分开只是为了演示方便,可以很直观的看到这一步匹配了什么,不然一步到位匹配完成,你都不知道发生了什么就处理完毕了。来看
2、下他的正则 复制代码 代码如下:(/s+|s+$/) / 匹配首尾空格(/("')(?:.|n)*?1/) / 匹配字符串(/(?!*|span).+/(?!span)gim*/) / 匹配正则 span 是他上次处理加上的,我觉得这里不应该出现(/(/.*|/*Ss+?*/)/) / 匹配注释(/(*s*)(w+)(?=s*)/) / 匹配 注释中的标记(/b(break|continue|do|for|in|function|if|else|return|switch|throw|try|catch|finally|var|while|with|case|new|type
3、of|instance|delete|void|Object|Array|String|Number|Boolean|Function|RegExp|Date|Math|window|document|navigator|location|true|false|null|undefined|NaN)b/) / 匹配关键词 小胡子哥可能是不想重复造轮子,只是想弄清楚如何造这样的轮子而已,所以他写这个东西点到即止,没有深入详细的处理,做的比较粗糙。当然我也不是说他什么,只是简单评论一下而已,毕竟优秀的语法高亮插件多的是,没必要自己重复造,学习下原理即可。 我们再来分析下 次碳酸钴 这篇 如何实现正
4、则表达式的JavaScript的代码高亮其实这篇已经分析的非常详细了,我只能简单补充说明下。次碳酸钴 思维一向比较严谨,这篇文章之前我看了一个多小时,只能看个大概,这次重新分析了一遍,然后自己实现了一遍,竟然也花去我半天时间,不过非常值得,真心学到了很多。 先来看一下大体的逻辑吧。 复制代码 代码如下:(/.*|/*Ss+?*/) / 匹配注释("')(?:.|n)*?3) / 匹配字符串b(break|continue|do|for|in|function|if|else|return|switch|this|throw|try|catch|finally|var|whil
5、e|with|case|new|typeof|instance|delete|void)b / 匹配关键词b(Object|Array|String|Number|Boolean|Function|RegExp|Date|Math|window|document|navigator|location)b / 匹配内置对象b(true|false)b / 匹配布尔值b(null|undefined|NaN)b / 匹配各种空值, 我觉得这个和布尔值一组比较合适。(?:Wd|$)$w* / 匹配普通的变量名(0xX0-9a-fA-F+|d+(?:.d+)?(?:eEd+)?) / 匹配数字 (前者
6、不占用,这里就会有问题)(?:)|)(/(?!*)(?:.|/n)+?/gim*) / 匹配正则Ss / 其他不能匹配的任意值 原文对最后一个 Ss 的描述:我们必须匹配到每一个字符。因为它们都需要做一次HTML转义。然后下面有详细的代码。 这是一篇非常不错的文章,我前前后后至少看了不下10次了,前两天才差不多完全明白。 不过这个代码还有一些小小的瑕疵,比如字符串不能匹配折行那种,字符串匹配优化。 还有数字匹配不够全面只能匹配 0xff, 12.34, 1e3 这几类,如 .123 12.3e+3 等格式都无法匹配到。还有关键词顺序我觉得可以稍微优化下。因为 传统型NFA 引擎的只是从左往右匹
7、配,匹配到了就停止下一个分支的操作。所以把最常出现的关键词放前面,可以提升一部分性能。最后,最好是 new RegExp 这样对于代码量大的代码性能上会有所提升。 下面就给出我的正则和简单的demo吧。(其实只是对 次碳酸钴 源码的优化而已。)先来看正则部分: 复制代码 代码如下:(/.*|/*sS*?*/) / 匹配注释 没改("(?:"|sS)*"|'(?:'|sS)*') / 匹配注释 优化过b(true|false|null|undefined|NaN)b / 匹配 布尔和空值,这几个比较常用,分组提前b(var|for|if|el
8、se|return|this|while|new|function|switch|case|typeof|do|in|throw|try|catch|finally|with|instance|delete|void|break|continue)b / 匹配关键词,关键词顺序改了下b(document|Date|Math|window|Object|location|navigator|Array|String|Number|Boolean|Function|RegExp)b /内置对象,单词顺序改了下(?:Wd|$)$w* / 匹配普通的变量名 没改(0xX0-9a-fA-F+|d+(?:
9、.d+)?(?:eE+-?d+)?|.d+(?:eE+-?d+)?) / 匹配数字,修复了匹配(?:|)(/(?!*)(?:.|/n)+?/gim*) / 匹配正则,这个最复杂,情况很多,我暂时没实力修改sS / 匹配其他 合并了布尔和空值一个分组,然后优化了正则分组,所以比他减少了2个分组。他 2,3 是字符串分组,因为 ("') 捕获了前面的引号,而我的正则没这么做。这个 (true|false|null|undefined|NaN) 如果你不喜欢放在一个分组了,分开也行、是不是同一个分组,只是为了区分着色而已。sublime text 下 true|false|null
10、|undefined|NaN 都是一个颜色,而 notepad+ 则只着色了 true|false ,我只想说 呵呵。 好了,差不多该给例子了。我相信,不少人在看到这之前已经关掉了,或者只是拉了下滚动条然后关掉了。不过我写这个就是为了给这些认真看下来的朋友,只要有一个人看,我觉得就不会白写了。例子: 复制代码 代码如下:/ 单行注释/* * 多行注释 * date 2014-05-12 22:24:37 * name 测试一下 */var str1 = "123"456"var str2 = '123'456'var str3 = &quo
11、t;123456" var num = 123;var arr = 12, 12.34, .12, 1e3, 1e+3, 1e-3, 12.34e3, 12.34e+3, 12.34e-3, .1234e3;var arr = "12", "12.34", '.12, 1e3', '1e+3, 1e-3', '12.34e3, 12.34e+3, 12.34e-3', ".1234e3"var arr = /12", "12.34/, /"12/3
12、4"/; for (var i=0; i<1e3; i+) var node = document.getElementById("a"+i); arr.push(node); function test () return true;test(); (function(window, undefined) var _re_js = new RegExp('(/.*|/*sS*?*/)|("(?:"|sS)*"|'(?:'|sS)*')|b(true|false|null|undefined|Na
13、N)b|b(var|for|if|else|return|this|while|new|function|switch|case|typeof|do|in|throw|try|catch|finally|with|instance|delete|void|break|continue)b|b(document|Date|Math|window|Object|location|navigator|Array|String|Number|Boolean|Function|RegExp)b|(?:Wd|$)$w*|(0xX0-9a-fA-F+|d+(?:.d+)?(?:eE+-?d+)?|.d+(?
14、:eE+-?d+)?)|(?:|)(/(?!*)(?:.|/n)+?/gim*)|sS', 'g'); function prettify(node) var code = node.innerHTML.replace(/rn|rn/g, "n").replace(/s+|s+$/g, ""); code = code.replace(_re_js, function() var s, a = arguments; for (var i = 1; i <= 7; i+) if (s = ai) s = htmlEncode(
15、s); switch (i) case 1: /注释 com return '<span class="com">' + s + '</span>' case 2: /字符串 str return '<span class="str">' + s + '</span>' case 3: /true|false|null|undefined|NaN val return '<span class="val">
16、;' + s + '</span>' case 4: /关键词 kwd return '<span class="kwd">' + s + '</span>' case 5: /内置对象 obj return '<span class="obj">' + s + '</span>' case 6: /数字 num return '<span class="num">
17、39; + s + '</span>' case 7: /正则 reg return htmlEncode(a0).replace(s, '<span class="reg">' + s + '</span>'); return htmlEncode(a0); ); code = code.replace(/(?:s*s*|(?: )*(?: )*)(w+)b/g, ' * <span class="comkey">$1</span>
18、9;) / 匹配注释中的标记 .replace(/(w+)(s*(|(?: )*()|(w+)(s*=s*function|(?: )*=(?: )*function)/g, '<span class="func">$1</span>$2') / 匹配函数 return code; function htmlEncode(str) var i, s = /"&": /&/g, """: /"/g, "'": /'/g, &q
19、uot;<": /g, "<br>": /n/g, " ": / /g, " ": /t/g ; for (i in s) str = str.replace(si, i); return str; prettify = prettify;)(window); 你们可以用下面的代码进行测试。 代码: 复制代码 代码如下:<!doctype html><html lang="en"><head> <meta charset="UTF-8&
20、quot;> <title>test</title> <style> /* 高亮样式 */ *font-size:12px; codeword-break:break-all; .com color:#008000; /* 注释 */ .comkey color:#FFA500; /* 注释标记 */ .str color:#808080; /* 字符串 */ .val color:#000080; /* true|false|null|undefined|NaN */ .kwd color:#000080;font:bold 12px 'co
21、mic sans ms', sans-serif; /* 关键词 */ .obj color:#000080; /* 内置对象 */ .num color:#FF0000; /* 数字 */ .reg color:#8000FF; /* 正则 */ .func color:#A355B9; /* 函数 */ </style></head><body> <code id="regdemon">/ 单行注释/* * 多行注释 * date 2014-05-12 22:24:37 * name 测试一下 */var str1
22、 = "123"456"var str2 = '123'456'var str3 = "123456" var num = 123;var arr = 12, 12.34, .12, 1e3, 1e+3, 1e-3, 12.34e3, 12.34e+3, 12.34e-3, .1234e3;var arr = "12", "12.34", '.12, 1e3', '1e+3, 1e-3', '12.34e3, 12.34e+3, 12.34e
23、-3', ".1234e3"var arr = /12", "12.34/, /"12/34"/; for (var i=0; i<1e3; i+) var node = getElementById("a"+i); arr.push(node); function test () return true;test(); (function(window, undefined) var _re_js = new RegExp('(/.*|/*sS*?*/)|("(?:"|s
24、S)*"|'(?:'|sS)*')|b(true|false|null|undefined|NaN)b|b(var|for|if|else|return|this|while|new|function|switch|case|typeof|do|in|throw|try|catch|finally|with|instance|delete|void|break|continue)b|b(document|Date|Math|window|Object|location|navigator|Array|String|Number|Boolean|Function
25、|RegExp)b|(?:Wd|$)$w*|(0xX0-9a-fA-F+|d+(?:.d+)?(?:eE+-?d+)?|.d+(?:eE+-?d+)?)|(?:|)(/(?!*)(?:.|/n)+?/gim*)|sS', 'g'); function prettify(node) var code = node.innerHTML.replace(/rn|rn/g, "n").replace(/s+|s+$/g, ""); code = code.replace(_re_js, function() var s, a = argu
26、ments; for (var i = 1; i <= 7; i+) if (s = ai) s = htmlEncode(s); switch (i) case 1: /注释 com return '<span class="com">' + s + '</span>' case 2: /字符串 str return '<span class="str">' + s + '</span>' case 3: /true|false|nul
27、l|undefined|NaN val return '<span class="val">' + s + '</span>' case 4: /关键词 kwd return '<span class="kwd">' + s + '</span>' case 5: /内置对象 obj return '<span class="obj">' + s + '</span>'
28、 case 6: /数字 num return '<span class="num">' + s + '</span>' case 7: /正则 reg return htmlEncode(a0).replace(s, '<span class="reg">' + s + '</span>'); return htmlEncode(a0); ); code = code.replace(/(?:s*s*|(?: )*(?: )*)(w+)b/g
29、, ' * <span class="comkey">$1</span>') / 匹配注释中的标记 .replace(/(w+)(s*(|(?: )*()|(w+)(s*=s*function|(?: )*=(?: )*function)/g, '<span class="func">$1</span>$2') / 匹配函数 return code; function htmlEncode(str) var i, s = /"&": /&/
30、g, """: /"/g, "'": /'/g, "<": /</g, ">": />/g, "<br>": /n/g, " ": / /g, " ": /t/g ; for (i in s) str = str.replace(si, i); return str; window.prettify = prettify;)(window);</code> <scri
31、pt>(function(window, undefined) var _re_js = new RegExp('(/.*|/*sS*?*/)|("(?:"|sS)*"|'(?:'|sS)*')|b(true|false|null|undefined|NaN)b|b(var|for|if|else|return|this|while|new|function|switch|case|typeof|do|in|throw|try|catch|finally|with|instance|delete|void|break|cont
32、inue)b|b(document|Date|Math|window|Object|location|navigator|Array|String|Number|Boolean|Function|RegExp)b|(?:Wd|$)$w*|(0xX0-9a-fA-F+|d+(?:.d+)?(?:eE+-?d+)?|.d+(?:eE+-?d+)?)|(?:|)(/(?!*)(?:.|/n)+?/gim*)|sS', 'g'); function prettify(node) var code = node.innerHTML.replace(/rn|rn/g, "
33、n").replace(/s+|s+$/g, ""); code = code.replace(_re_js, function() var s, a = arguments; for (var i = 1; i <= 7; i+) if (s = ai) s = htmlEncode(s); switch (i) case 1: /注释 com return '<span class="com">' + s + '</span>' case 2: /字符串 str return &
34、#39;<span class="str">' + s + '</span>' case 3: /true|false|null|undefined|NaN val return '<span class="val">' + s + '</span>' case 4: /关键词 kwd return '<span class="kwd">' + s + '</span>' case 5: /内置对象 obj return '<span class=&q
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年公共图书馆总分馆制建设评估报告
- 2025YY平台域名转让合同样本
- 毕业活动策划方案大学活动策划
- 2025年中国孔明灯行业市场调查研究及发展战略规划报告
- 教师节表彰大会活动策划方案
- 2025-2030年中国灶石项目投资可行性研究分析报告
- 2025年医用内窥镜部件行业市场研究报告
- 四班级教育教学工作方案怎么写
- 推广普通话宣传周实施策划方案
- “十三五”重点项目-硅胶止血袖带项目可行性研究报告
- 2025至2030中国矿用排水泵行业深度研究及发展前景投资评估分析
- 2025届北京市十一所学校物理高一下期末监测试题含解析
- 小学英语-三年级升四年级英语阅读理解专项(附答案)
- 民警工作纪律培训课件
- 2025年高考真题-政治(云南卷) 含答案
- 学堂在线 生活英语进阶 章节测试答案
- 2025年辅警面试考试练习题目及答案解析
- 党徽党旗条例全面解读
- 2025至2030中国原煤行业市场深度发展趋势与前景展望战略报告
- 汽车总装座椅轮胎输送线技术要求
- 六大茶类培训
评论
0/150
提交评论