当前位置:  编程技术>其它

js 玩转正则表达式之语法高亮

    来源: 互联网  发布时间:2014-10-18

    本文导语:  学了几天正则,差不多该总结整理写成果了,之前就想写语法高亮匹配来着,不过水平不够,看着例子都不理解。 那么我们来分析下两位大神 次碳酸钴 和 Barret Lee 语法高亮实现。 先说 Barret Lee 的这篇 《几个小例子教你如何...

学了几天正则,差不多该总结整理写成果了,之前就想写语法高亮匹配来着,不过水平不够,看着例子都不理解。

那么我们来分析下两位大神 次碳酸钴 和 Barret Lee 语法高亮实现。

先说 Barret Lee 的这篇 《几个小例子教你如何实现正则表达式highlight高亮》

之前看的时候只觉的神奇,特别是下面那个一步一步分开匹配的例子,更是霸气测漏,不过作者也说了,分开只是为了演示方便,可以很直观的看到这一步匹配了什么,不然一步到位匹配完成,你都不知道发生了什么就处理完毕了。
来看下他的正则

代码如下:

(/^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|typeof|instance|delete|void|Object|Array|String|Number|Boolean|Function|RegExp|Date|Math|window|document|navigator|location|true|false|null|undefined|NaN)b/) // 匹配关键词

小胡子哥可能是不想重复造轮子,只是想弄清楚如何造这样的轮子而已,所以他写这个东西点到即止,没有深入详细的处理,做的比较粗糙。
当然我也不是说他什么,只是简单评论一下而已,毕竟优秀的语法高亮插件多的是,没必要自己重复造,学习下原理即可。

我们再来分析下 次碳酸钴 这篇 《如何实现正则表达式的JavaScript的代码高亮》
其实这篇已经分析的非常详细了,我只能简单补充说明下。
次碳酸钴 思维一向比较严谨,这篇文章之前我看了一个多小时,只能看个大概,这次重新分析了一遍,然后自己实现了一遍,竟然也花去我半天时间,
不过非常值得,真心学到了很多。

先来看一下大体的逻辑吧。

代码如下:

(//.*|/*[Ss]+?*/) // 匹配注释
((["'])(?:\.|[^\n])*?3) // 匹配字符串
b(break|continue|do|for|in|function|if|else|return|switch|this|throw|try|catch|finally|var|while|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]* // 匹配普通的变量名
(0[xX][0-9a-fA-F]+|d+(?:.d+)?(?:[eE]d+)?) // 匹配数字 (前者不占用,这里就会有问题)
(?:[^)]}]|^)(/(?!*)(?:\.|[^\/n])+?/[gim]*) // 匹配正则
[Ss] // 其他不能匹配的任意值

原文对最后一个 [Ss] 的描述:我们必须匹配到每一个字符。因为它们都需要做一次HTML转义。
然后下面有详细的代码。

这是一篇非常不错的文章,我前前后后至少看了不下10次了,前两天才差不多完全明白。

不过这个代码还有一些小小的瑕疵,比如字符串不能匹配折行那种,字符串匹配优化。

还有数字匹配不够全面只能匹配 0xff, 12.34, 1e3 这几类,如 .123 12.3e+3 等格式都无法匹配到。
还有关键词顺序我觉得可以稍微优化下。
因为 传统型NFA 引擎的只是从左往右匹配,匹配到了就停止下一个分支的操作。
所以把最常出现的关键词放前面,可以提升一部分性能。
最后,最好是 new RegExp 这样对于代码量大的代码性能上会有所提升。

下面就给出我的正则和简单的demo吧。(其实只是对 次碳酸钴 源码的优化而已。。)
先来看正则部分:

代码如下:

(//.*|/*[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|continue)b // 匹配关键词,关键词顺序改了下
b(document|Date|Math|window|Object|location|navigator|Array|String|Number|Boolean|Function|RegExp)b //内置对象,单词顺序改了下
(?:[^Wd]|$)[$w]* // 匹配普通的变量名 没改
(0[xX][0-9a-fA-F]+|d+(?:.d+)?(?:[eE][+-]?d+)?|.d+(?:[eE][+-]?d+)?) // 匹配数字,修复了匹配
(?:^|[^)]}])(/(?!*)(?:\.|[^\/n])+?/[gim]*) // 匹配正则,这个最复杂,情况很多,我暂时没实力修改
[sS] // 匹配其他

合并了布尔和空值一个分组,然后优化了正则分组,所以比他减少了2个分组。
他 2,3 是字符串分组,因为 (["']) 捕获了前面的引号,而我的正则没这么做。
这个 (true|false|null|undefined|NaN) 如果你不喜欢放在一个分组了,分开也行、
是不是同一个分组,只是为了区分着色而已。
sublime text 下 true|false|null|undefined|NaN 都是一个颜色,而 notepad++ 则只着色了 true|false ,我只想说 呵呵。

好了,差不多该给例子了。
我相信,不少人在看到这之前已经关掉了,或者只是拉了下滚动条然后关掉了。
不过我写这个就是为了给这些认真看下来的朋友,只要有一个人看,我觉得就不会白写了。
例子:

代码如下:

// 单行注释
/**
 * 多行注释
 * @date 2014-05-12 22:24:37
 * @name 测试一下
 */
var str1 = "123"456";
var str2 = '123'456';
var str3 = "123
456";

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/34"/];

for (var i=0; i/g,
                "
": /n/g,
                " ": / /g,
                "  ": /t/g
            };
        for (i in s) {
            str = str.replace(s[i], i);
        }
        return str;
    }

    window.prettify = prettify;
})(window);


(function(window, undefined) {
    var _re_js = new RegExp('(\/\/.*|\/\*[\s\S]*?\*\/)|("(?:[^"\\]|\\[\s\S])*"|'(?:[^'\\]|\\[\s\S])*')|\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|RegExp)\b|(?:[^\W\d]|\$)[\$\w]*|(0[xX][0-9a-fA-F]+|\d+(?:\.\d+)?(?:[eE][+-]?\d+)?|\.\d+(?:[eE][+-]?\d+)?)|(?:^|[^\)\]\}])(\/(?!\*)(?:\\.|[^\\\/\n])+?\/[gim]*)|[\s\S]', '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


    
 
 

您可能感兴趣的文章:

  • 几个小例子教你如何实现正则表达式highlight高亮
  • 如何实现正则表达式的JavaScript的代码高亮
  • Perl 正则表达式之角色化记忆
  • js正则表达式之RegExp对象之compile方法 编译正则表达式
  • Linux c++ boost库正则表达式用法
  • 正则表达式 表示 非指定字符串开头的正则
  • Python通过正则表达式获取,去除(过滤)或者替换HTML标签的几种方法
  • 正则表达式问题,使用正则表达式找出指定字符串并替换?
  • linux bash shell命令:文本搜索工具grep正则表达式元字符集(基本集)
  • 正则表达式概述 什么是正则表达式 .
  • JS 正则表达式的相关方法(正则学习笔记1)
  • jQuery中的正则表达式分析 正则基础
  • java 正则表达式基础,实例学习资料收集大全 原创
  • 哪些命令可以使用正则表达式
  • 常用正则表达式及评注-学习正则必备
  • (菜鸟飞飞)问个正则表达式的问题
  • 向大家推荐一个收集整理正则表达式的网站
  • 正则表达式的问题
  • 关于正则表达式匹配问题
  • Python 匹配任意字符(包括换行符)的正则表达式写法
  • php 正则 不包含某字符串的正则表达式
  • Java正则表达式 reb4j
  • 大虾,请问谁有正则表达式的资料?谢谢!
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • c#正则过滤图片标签 asp.net正则过滤的例子
  • 正则匹配后面非指定字符的正则 原创
  • java使用正则表达校验手机号码示例(手机号码正则)
  • PHP html标签正则替换并可自定义正则规则
  • python正则表达式去掉数字中的逗号(python正则匹配逗号)
  • 正则表达式口诀_学习正则的朋友值得一看
  • Javascript里的两种使用正则的方法
  • 常用正则 常用的C#正则表达式
  • 寻求正则表达试
  • 学习IP地址的正则表达式
  • asp.net正则表达式提取中文的代码示例
  • 正则表达式中使用变量赋值
  • 用正则表达式来表示中文
  • java正则表达式验证函数
  • linux下有什么函数可以处理正则表达式?
  • emacs里空行的正则表达式如何写?
  • 正则式 ^[^ ](.*[^ ])?$ 的含义
  • 正则式如何只匹配一个汉字?
  • 关于sed的正则表达式
  • 正则表达式小疑问




  • 特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3