如何实现正则表达式的JavaScript的代码高亮

今天想改一下JS的高亮的配色,憋了一下午憋出了这个这个正则表达式。

下面这老长老长了的玩意儿是个正则表达式,看到了别吓坏了。

/(\/\/.*|\/\*[\S\s]+?\*\/)|((["'])(?:\\.|[^\\\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|(?:[^\W\d]|\$)[\$\w]*|(0[xX][0-9a-fA-F]+|\d+(?:\.\d+)?(?:[eE]\d+)?)|(?:[^\)\]\}]|^)(\/(?!\*)(?:\\.|[^\\\/\n])+?\/[gim]*)|[\S\s]/g

现在,我们可以来慢慢分析它。仔细看这个正则表达式你会发现,它们是很多个正则表达式用|连接起来的。现在,我们把它用|分割,逐个分析。

(\/\/.*|\/\*[\S\s]+?\*\/)

这是第二个,这个正则表达式是用来匹配字符串的。字符串可以在单引号和双引号中,所以我们匹配这两个的任意一个。这里需要用一个括号把它括起来表示它是一个获取匹配(“获取匹配”的“获取”是名词),因为在结束的地方还需要匹配这个字符。在匹配字符串结束的地方可以用后向引用\3来匹配字符串开始的字符,也就是开始时的引号种类。如果你从这整个正则表达式的开头开始数,你就会发现["']外面的括号是整个正则表达式中的第三个获取匹配。这就是字符串的头尾部分,中间的部分由于字符串是可以包含转义的,所以我们一旦遇到反斜杠就直接跳过它后面那个字符,因为反斜杠后面包含的是转义。但是这仅仅是匹配转义,所以我们要用或运算|连接一个匹配非转义的表达式,那就是[^\\]。可是这个是匹配非反斜杠的任何字符,它可以包含换行,而JS中的字符串是不允许写成换行的。所以我们需要加个\n让它不匹配换行。由于我们使用了或来连接,而或的优先级非常低,所以需要在旁边加上括号来修正优先级。如果使用普通的括号就会占用一个获取匹配,所以我们要使用(?:)来完成一个非获取匹配。

\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

这是第3、4、5、6个,这些只是匹配一些关键字,由于需要的颜色不同所以被分组了。这没什么好说的,跳过。

(?:[^\W\d]|\$)[\$\w]*

这是第七个,它的作用是匹配普通的变量名。如果变量名的字符不消耗掉,后面匹配数字的就有可能会把变量名中的数字匹配输出来。所以这一步是必须的。你会发现这一步没有任何获取匹配,因为变量名的颜色是默认颜色,我们不获取它。根据JS的命名规则,变量名是不能以数字开头的,所以我们用[^\W\d]|\$匹配一个变量的开头。后面则可以匹配数字、字母、下划线、美元符号,任意次。这样变量名就被消耗掉了。

(0[xX][0-9a-fA-F]+|\d+(?:\.\d+)?(?:[eE]\d+)?)

这是第八个,匹配数字的。由于数字的表达方式有两种,所以我们要分开写。|的左边是16进制的数字写法。右边是普通的数字写法,这个可以包含小数和科学计数法。由于小数和科学计数法都是可选存在的,所以我们把它括号起来,后面加上问号作为可选匹配。

(?:[^\)\]\}]|^)(\/(?!\*)(?:\\.|[^\\\/\n])+?\/[gim]*)

这是第九个,匹配正则表达式的。前面有个非获取匹配,匹配非括号的结束。因为如果存在括号,那么斜杆就有可能表示的是除号而不是正则表达式了。后面就是正则表达式的匹配,和字符串的匹配类似,只不过最后多了一个[gim]*。这是正则表达式的三种匹配模式,也是属于正则表达式的范畴,所以我们要匹配并获取它。

[\S\s]

最后一个是匹配所有上面没有匹配到的字符,我们必须匹配到每一个字符。因为它们都需要做一次HTML转义。

这样,这个长长的正则就分析完了。下面是实现的例子。

//读入当前代码

var code=document.getElementById("code").innerHTML;

//修正换行的浏览器差异,去掉头尾的换行和空格

code=code.replace(/\r\n|[\r\n]/g,"\n").replace(/^\s+|\s+$/g,"");

//开始主匹配

code=code.replace(/(\/\/.*|\/\*[.\s]+?\*\/)|((["'])(?:\\.|[^\\\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|(?:[^\W\d]|\$)[\$\w]*|(0[xX][0-9a-fA-F]+|\d+(?:\.\d+)?(?:[eE]\d+)?)|(?:[^\)\]\}]|^)(\/(?!\*)(?:\\.|[^\\\/\n])+?\/[gim]*)|[.\s]/g,function(){

var a,l,i,s;

a=arguments;

//循环匹配到的位置

for(i=1;i<=9;i++)if(s=a[i]){

s=htmlEncode(s);

//每个获取匹配的位置都着上不同的颜色

switch(i){

case 1://注释

return s.fontcolor("#998877").italics();

case 2:case 3://字符串

return s.fontcolor("#AA5544");

case 4://关键词

return s.fontcolor("#333388");

case 5://内置对象

return s.fontcolor("#5555AA");

case 6://布尔值

return s.fontcolor("#DD6600");

case 7://空值

return s.fontcolor("#BB4433");

case 8://数字

return s.fontcolor("#CC3322");

case 9://正则表达式

//这个比较特殊,匹配到的和获取的有些不同

//匹配的时候,前面有个非获取匹配,所以我们要保留非获取匹配的部分

return htmlEncode(a[0]).replace(s,s.fontcolor("#33AA33"));

};

};

//没有获取匹配就直接转义输出

return htmlEncode(a[0]);

});

//输出结果

document.write(code);

//HTML的转义函数

function htmlEncode(e){

var i,s;

for(i in s={

"&":/&/g,""":/"/g,"'":/'/g,

"":/>/g,"
":/\n/g,

" ":/ /g,"  ":/\t/g

})e=e.replace(s[i],i);

return e;

};

由于今天在赶这篇文章,没时间做这个代码的优化了。应该还有很多小漏洞,不过整体思路就是这样。这样无论是JS还是其它什么语言,代码高亮都可以直接正则匹配出来。相关阅读:

Win10 Edge浏览器和EdgeHTML的区别介绍

win10本地账户怎么切换成microsoft账户?

MySQL replace into 语句浅析(二)

解读PHP中的垃圾回收机制

Java Mail与Apache Mail发送邮件示例

MySQL触发器使用详解

js实现字符串和数组之间相互转换操作

JavaScript函数的一些注意要点小结及js匿名函数

Win7声音受到其他程序的干扰忽大忽小的修复技巧

学习DIV+CSS网页布局之混合布局

Android遍历所有文件夹和子目录搜索文件

使用WindowsAPI实现播放PCM音频的方法

Win7通过禁用nvcpl服务项减少开机时间提高开机速度

C#获取指定文件著作权信息的方法

js中怎么使用php代码高亮,PHP_如何实现正则表达式的JavaScript的代码高亮,今天想改一下JS的高亮的配色 - phpStudy...相关推荐

  1. php项目打开快捷方式,PHP_克隆一个新项目的快捷方式,有没想过最土的项目如何快速 - phpStudy...

    克隆一个新项目的快捷方式 有没想过最土的项目如何快速复制出一个来,然后改改就成新的团购项目了? 或者说编辑一个老项目的时候想把他另存为一个新项目而不是保存, 看下图 红色部分 具体开发代码(非细节), ...

  2. js中load载入html页面,使用jquery的load方法加载html页面,但是html引入的js不生效

    Write By Monkeyfly 以下内容均为原创,如需转载请注明出处. 前提 有一个公共的登录弹框页面需要在多个页面引用,百度后就使用了jQuery 的 load 方法. 做法: 将公共的 ht ...

  3. js中遍历数组加到新数组_js数组遍历:JavaScript如何遍历数组?

    什么是数组的遍历? 操作数组中的每一个数组元素. 使用for循环来遍历数组 因为数组的下标是连续的,数组的下标是从0开始. 我们也可以得到数组的长度. 格式:for(var i=0;i 数组变量名[i ...

  4. php模拟红绿灯,JS 中使用Promise 实现红绿灯实例代码(demo)

    本文通过实例代码给大家介绍了JS 中使用Promise 实现红绿灯效果,在文中给大家介绍了一个promise用法例子,不了解js中如何使用Promise的朋友可以参考下本篇文章 要求使用promise ...

  5. js三元运算符_这些优化技巧可以避免我们在 JS 中过多的使用 IF 语句

    最近在重构代码时,我发现早期的代码使用太多的 if 语句,其程度是我从未见过的.这就是为什么我认为分享这些简单的技巧是非常重要的,这些技巧可以帮助我们避免过多的使用 if 语句. 接下来会介绍6种方式 ...

  6. vue中引用js_从JS中的内存管理说起 —— JS中的弱引用

    点击上方"蓝字"关注本公众号 写在前面 在所有的编程语言中,我们声明一个变量时,需要系统为我们分配一块内存.当我们不再需要这个变量时,需要将内存进行回收(这个过程称之为垃圾回收). ...

  7. JS中的数据类型转换

    ES5中一共有6种数据类型,其中5种基本类型(String.Number.Boolean.Null.Undefined),1种引用类型(Object).基本类型值可以相互换转换,并且引用类型值也可以通 ...

  8. JS中的Replace方法

    最近查一个bug,原因是JS中的Replace方法造成的,当将一个字符串中有处需要替换时,一般会用到JS中的Replace方法,Replace方法的第一个参数如果是传的字符串,只会替换第一处.代码如下 ...

  9. 第22篇 js中的this指针的用法

    前面把js的相关知识总结了下,今天把js中的上下文的this,对于强类型语言,this的用法非常的单一,因为他们没有js特有的动态绑定. 首先看下面代码: function funcA() {this ...

最新文章

  1. 一次使用Eclipse Memory Analyzer分析weblogic内存溢出
  2. 【Linux】一步一步学Linux——rmdir命令(22)
  3. IOCP配合AcceptEx的例子
  4. BZOJ2240 : ural1676 Mortal Combat
  5. WPF编游戏系列 之六 动画效果(1)
  6. Vivado设计DDR3接口生成bit报错解决
  7. fastdfs windows部署_从零搭建分布式文件系统MinIO比FastDFS要更合适
  8. (转)javascript 从数组中删除指定值(不是指定位置)的元素
  9. Antelope 和Barracuda区别
  10. 虚拟麦克风音频输入_Audio Precision 全新声学/音频分析软件可减少测试时间
  11. java.util.LinkedHashMap cannot be cast to
  12. 苹果计算机打音乐,给苹果手机“隔空投送”更多的音乐和文件!
  13. java获得时间差_Java获取时间差实例代码详解
  14. 求不规则立方体表面积java_求立方体的体积、表面积(c++)
  15. 【Codecs系列】视频编码中的率失真优化RDO技术
  16. 胆囊炎的临床症状有哪些?
  17. HTML5轻松实现全屏视频背景
  18. 美国主机BlueHost vs HostEase
  19. 当夫子邂逅舞池——读《花鼓歌》
  20. 身份证号码编码方法及校验算法

热门文章

  1. LaTeX中三种列举的形式:itemize,enumerate,description
  2. ROG 幻 16 翻转版 2023款评测 ROG 幻 16 翻转版 2023参数配置
  3. android 酷狗demo_Android 本地播放器
  4. Linux下Redis使用RPM方式安装
  5. 使用QT5完成一个数据实时显示控制的Demo
  6. @Qualifier的作用
  7. c语言编译舞动的红旗,C语言程序设计 飘动的红旗
  8. 整车出厂 合格证 V3.0
  9. 提交的JDK输入法光标跟随,被要求予以详细说明
  10. Java中int和long数据类型转换及溢出问题