js玩轉(zhuǎn)正則表達式之語法高亮_第1頁
js玩轉(zhuǎn)正則表達式之語法高亮_第2頁
js玩轉(zhuǎn)正則表達式之語法高亮_第3頁
js玩轉(zhuǎn)正則表達式之語法高亮_第4頁
js玩轉(zhuǎn)正則表達式之語法高亮_第5頁
已閱讀5頁,還剩5頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、js 玩轉(zhuǎn)正則表達式之語法高亮學了幾天正則,差不多該總結(jié)整理寫成果了,通過分析2位大神的代碼,整理出來的一篇很實用的文章學了幾天正則,差不多該總結(jié)整理寫成果了,之前就想寫語法高亮匹配來著,不過水平不夠,看著例子都不理解。 那么我們來分析下兩位大神 次碳酸鈷 和 Barret Lee 語法高亮實現(xiàn)。 先說 Barret Lee 的這篇 幾個小例子教你如何實現(xiàn)正則表達式highlight高亮 之前看的時候只覺的神奇,特別是下面那個一步一步分開匹配的例子,更是霸氣測漏,不過作者也說了,分開只是為了演示方便,可以很直觀的看到這一步匹配了什么,不然一步到位匹配完成,你都不知道發(fā)生了什么就處理完畢了。來看

2、下他的正則 復制代碼 代碼如下:(/s+|s+$/) / 匹配首尾空格(/("')(?:.|n)*?1/) / 匹配字符串(/(?!*|span).+/(?!span)gim*/) / 匹配正則 span 是他上次處理加上的,我覺得這里不應該出現(xiàn)(/(/.*|/*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/) / 匹配關(guān)鍵詞 小胡子哥可能是不想重復造輪子,只是想弄清楚如何造這樣的輪子而已,所以他寫這個東西點到即止,沒有深入詳細的處理,做的比較粗糙。當然我也不是說他什么,只是簡單評論一下而已,畢竟優(yōu)秀的語法高亮插件多的是,沒必要自己重復造,學習下原理即可。 我們再來分析下 次碳酸鈷 這篇 如何實現(xiàn)正

4、則表達式的JavaScript的代碼高亮其實這篇已經(jīng)分析的非常詳細了,我只能簡單補充說明下。次碳酸鈷 思維一向比較嚴謹,這篇文章之前我看了一個多小時,只能看個大概,這次重新分析了一遍,然后自己實現(xiàn)了一遍,竟然也花去我半天時間,不過非常值得,真心學到了很多。 先來看一下大體的邏輯吧。 復制代碼 代碼如下:(/.*|/*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 / 匹配關(guān)鍵詞b(Object|Array|String|Number|Boolean|Function|RegExp|Date|Math|window|document|navigator|location)b / 匹配內(nèi)置對象b(true|false)b / 匹配布爾值b(null|undefined|NaN)b / 匹配各種空值, 我覺得這個和布爾值一組比較合適。(?:Wd|$)$w* / 匹配普通的變量名(0xX0-9a-fA-F+|d+(?:.d+)?(?:eEd+)?) / 匹配數(shù)字 (前者

6、不占用,這里就會有問題)(?:)|)(/(?!*)(?:.|/n)+?/gim*) / 匹配正則Ss / 其他不能匹配的任意值 原文對最后一個 Ss 的描述:我們必須匹配到每一個字符。因為它們都需要做一次HTML轉(zhuǎn)義。然后下面有詳細的代碼。 這是一篇非常不錯的文章,我前前后后至少看了不下10次了,前兩天才差不多完全明白。 不過這個代碼還有一些小小的瑕疵,比如字符串不能匹配折行那種,字符串匹配優(yōu)化。 還有數(shù)字匹配不夠全面只能匹配 0xff, 12.34, 1e3 這幾類,如 .123 12.3e+3 等格式都無法匹配到。還有關(guān)鍵詞順序我覺得可以稍微優(yōu)化下。因為 傳統(tǒng)型NFA 引擎的只是從左往右匹

7、配,匹配到了就停止下一個分支的操作。所以把最常出現(xiàn)的關(guān)鍵詞放前面,可以提升一部分性能。最后,最好是 new RegExp 這樣對于代碼量大的代碼性能上會有所提升。 下面就給出我的正則和簡單的demo吧。(其實只是對 次碳酸鈷 源碼的優(yōu)化而已。)先來看正則部分: 復制代碼 代碼如下:(/.*|/*sS*?*/) / 匹配注釋 沒改("(?:"|sS)*"|'(?:'|sS)*') / 匹配注釋 優(yōu)化過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 / 匹配關(guān)鍵詞,關(guān)鍵詞順序改了下b(document|Date|Math|window|Object|location|navigator|Array|String|Number|Boolean|Function|RegExp)b /內(nèi)置對象,單詞順序改了下(?:Wd|$)$w* / 匹配普通的變量名 沒改(0xX0-9a-fA-F+|d+(?:

9、.d+)?(?:eE+-?d+)?|.d+(?:eE+-?d+)?) / 匹配數(shù)字,修復了匹配(?:|)(/(?!*)(?:.|/n)+?/gim*) / 匹配正則,這個最復雜,情況很多,我暫時沒實力修改sS / 匹配其他 合并了布爾和空值一個分組,然后優(yōu)化了正則分組,所以比他減少了2個分組。他 2,3 是字符串分組,因為 ("') 捕獲了前面的引號,而我的正則沒這么做。這個 (true|false|null|undefined|NaN) 如果你不喜歡放在一個分組了,分開也行、是不是同一個分組,只是為了區(qū)分著色而已。sublime text 下 true|false|null

10、|undefined|NaN 都是一個顏色,而 notepad+ 則只著色了 true|false ,我只想說 呵呵。 好了,差不多該給例子了。我相信,不少人在看到這之前已經(jīng)關(guān)掉了,或者只是拉了下滾動條然后關(guān)掉了。不過我寫這個就是為了給這些認真看下來的朋友,只要有一個人看,我覺得就不會白寫了。例子: 復制代碼 代碼如下:/ 單行注釋/* * 多行注釋 * 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: /關(guān)鍵詞 kwd return '<span class="kwd">' + s + '</span>' case 5: /內(nèi)置對象 obj return '<span class="obj">' + s + '</span>' case 6: /數(shù)字 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') / 匹配函數(shù) 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; /* 關(guān)鍵詞 */ .obj color:#000080; /* 內(nèi)置對象 */ .num color:#FF0000; /* 數(shù)字 */ .reg color:#8000FF; /* 正則 */ .func color:#A355B9; /* 函數(shù) */ </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: /關(guān)鍵詞 kwd return '<span class="kwd">' + s + '</span>' case 5: /內(nèi)置對象 obj return '<span class="obj">' + s + '</span>'

28、 case 6: /數(shù)字 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') / 匹配函數(shù) 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: /關(guān)鍵詞 kwd return '<span class="kwd">' + s + '</span>' case 5: /內(nèi)置對象 obj return '<span class=&q

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論