久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放AV片

<center id="vfaef"><input id="vfaef"><table id="vfaef"></table></input></center>

    <p id="vfaef"><kbd id="vfaef"></kbd></p>

    
    
    <pre id="vfaef"><u id="vfaef"></u></pre>

      <thead id="vfaef"><input id="vfaef"></input></thead>

    1. 站長(zhǎng)資訊網(wǎng)
      最全最豐富的資訊網(wǎng)站

      js 玩轉(zhuǎn)正則表達(dá)式之語法高亮

      學(xué)了幾天正則,差不多該總結(jié)整理寫成果了,之前就想寫語法高亮匹配來著,不過水平不夠,看著例子都不理解。

      那么我們來分析下兩位大神 次碳酸鈷 和 Barret Lee 語法高亮實(shí)現(xiàn)。

      先說 Barret Lee 的這篇 《幾個(gè)小例子教你如何實(shí)現(xiàn)正則表達(dá)式highlight高亮》

      之前看的時(shí)候只覺的神奇,特別是下面那個(gè)一步一步分開匹配的例子,更是霸氣測(cè)漏,不過作者也說了,分開只是為了演示方便,可以很直觀的看到這一步匹配了什么,不然一步到位匹配完成,你都不知道發(fā)生了什么就處理完畢了。
      來看下他的正則

      復(fù)制代碼 代碼如下:
      (/^s+|s+$/) // 匹配首尾空格
      (/([“‘])(?:\.|[^\n])*?1/) // 匹配字符串
      (//(?!*|span).+/(?!span)[gim]*/) // 匹配正則 span 是他上次處理加上的,我覺得這里不應(yīng)該出現(xiàn)
      (/(//.*|/*[Ss]+?*/)/) // 匹配注釋
      (/(*s*)(@w+)(?=s*)/) // 匹配 注釋中的標(biāo)記
      (/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/) // 匹配關(guān)鍵詞

      小胡子哥可能是不想重復(fù)造輪子,只是想弄清楚如何造這樣的輪子而已,所以他寫這個(gè)東西點(diǎn)到即止,沒有深入詳細(xì)的處理,做的比較粗糙。
      當(dāng)然我也不是說他什么,只是簡(jiǎn)單評(píng)論一下而已,畢竟優(yōu)秀的語法高亮插件多的是,沒必要自己重復(fù)造,學(xué)習(xí)下原理即可。

      我們?cè)賮矸治鱿?次碳酸鈷 這篇 《如何實(shí)現(xiàn)正則表達(dá)式的JavaScript的代碼高亮》
      其實(shí)這篇已經(jīng)分析的非常詳細(xì)了,我只能簡(jiǎn)單補(bǔ)充說明下。
      次碳酸鈷 思維一向比較嚴(yán)謹(jǐn),這篇文章之前我看了一個(gè)多小時(shí),只能看個(gè)大概,這次重新分析了一遍,然后自己實(shí)現(xiàn)了一遍,竟然也花去我半天時(shí)間,
      不過非常值得,真心學(xué)到了很多。

      先來看一下大體的邏輯吧。

      復(fù)制代碼 代碼如下:
      (//.*|/*[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 // 匹配關(guān)鍵詞
      b(Object|Array|String|Number|Boolean|Function|RegExp|Date|Math|window|document|navigator|location)b // 匹配內(nèi)置對(duì)象
      b(true|false)b // 匹配布爾值
      b(null|undefined|NaN)b // 匹配各種空值, 我覺得這個(gè)和布爾值一組比較合適。
      (?:[^Wd]|$)[$w]* // 匹配普通的變量名
      (0[xX][0-9a-fA-F]+|d+(?:.d+)?(?:[eE]d+)?) // 匹配數(shù)字 (前者不占用,這里就會(huì)有問題)
      (?:[^)]}]|^)(/(?!*)(?:\.|[^\/n])+?/[gim]*) // 匹配正則
      [Ss] // 其他不能匹配的任意值

      原文對(duì)最后一個(gè) [Ss] 的描述:我們必須匹配到每一個(gè)字符。因?yàn)樗鼈兌夹枰鲆淮蜨TML轉(zhuǎn)義。
      然后下面有詳細(xì)的代碼。

      這是一篇非常不錯(cuò)的文章,我前前后后至少看了不下10次了,前兩天才差不多完全明白。

      不過這個(gè)代碼還有一些小小的瑕疵,比如字符串不能匹配折行那種,字符串匹配優(yōu)化。

      還有數(shù)字匹配不夠全面只能匹配 0xff, 12.34, 1e3 這幾類,如 .123 12.3e+3 等格式都無法匹配到。
      還有關(guān)鍵詞順序我覺得可以稍微優(yōu)化下。
      因?yàn)?傳統(tǒng)型NFA 引擎的只是從左往右匹配,匹配到了就停止下一個(gè)分支的操作。
      所以把最常出現(xiàn)的關(guān)鍵詞放前面,可以提升一部分性能。
      最后,最好是 new RegExp 這樣對(duì)于代碼量大的代碼性能上會(huì)有所提升。

      下面就給出我的正則和簡(jiǎn)單的demo吧。(其實(shí)只是對(duì) 次碳酸鈷 源碼的優(yōu)化而已。。)
      先來看正則部分:

      復(fù)制代碼 代碼如下:
      (//.*|/*[sS]*?*/) // 匹配注釋 沒改
      (“(?:[^”\]|\[sS])*”|'(?:[^’\]|\[sS])*’) // 匹配注釋 優(yōu)化過
      b(true|false|null|undefined|NaN)b // 匹配 布爾和空值,這幾個(gè)比較常用,分組提前
      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 // 匹配關(guān)鍵詞,關(guān)鍵詞順序改了下
      b(document|Date|Math|window|Object|location|navigator|Array|String|Number|Boolean|Function|RegExp)b //內(nèi)置對(duì)象,單詞順序改了下
      (?:[^Wd]|$)[$w]* // 匹配普通的變量名 沒改
      (0[xX][0-9a-fA-F]+|d+(?:.d+)?(?:[eE][+-]?d+)?|.d+(?:[eE][+-]?d+)?) // 匹配數(shù)字,修復(fù)了匹配
      (?:^|[^)]}])(/(?!*)(?:\.|[^\/n])+?/[gim]*) // 匹配正則,這個(gè)最復(fù)雜,情況很多,我暫時(shí)沒實(shí)力修改
      [sS] // 匹配其他

      合并了布爾和空值一個(gè)分組,然后優(yōu)化了正則分組,所以比他減少了2個(gè)分組。
      他 2,3 是字符串分組,因?yàn)?([“‘]) 捕獲了前面的引號(hào),而我的正則沒這么做。
      這個(gè) (true|false|null|undefined|NaN) 如果你不喜歡放在一個(gè)分組了,分開也行、
      是不是同一個(gè)分組,只是為了區(qū)分著色而已。
      sublime text 下 true|false|null|undefined|NaN 都是一個(gè)顏色,而 notepad++ 則只著色了 true|false ,我只想說 呵呵。

      好了,差不多該給例子了。
      我相信,不少人在看到這之前已經(jīng)關(guān)掉了,或者只是拉了下滾動(dòng)條然后關(guān)掉了。
      不過我寫這個(gè)就是為了給這些認(rèn)真看下來的朋友,只要有一個(gè)人看,我覺得就不會(huì)白寫了。
      例子:

      復(fù)制代碼 代碼如下:
      // 單行注釋
      /**
       * 多行注釋
       * @date 2014-05-12 22:24:37
       * @name 測(cè)試一下
       */
      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<1e3; i++) {
        var node = document.getElementById(“a”+i);
        arr.push(node);
      }

      function test () {
        return true;
      }
      test();

       

      (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 <= 7; i++) {
                      if (s = a[i]) {
                          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|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)置對(duì)象 obj
                                  return ‘<span class=”obj”>’ + s + ‘</span>’;
                              case 6: //數(shù)字 num
                                  return ‘<span class=”num”>’ + s + ‘</span>’;
                              case 7: //正則 reg
                                  return htmlEncode(a[0]).replace(s, ‘<span class=”reg”>’ + s + ‘</span>’);
                          }
                      }
                  }
                  return htmlEncode(a[0]);
              });
              code = code.replace(/(?:s**s*|(?: )**(?: )*)(@w+)b/g, ‘ * <span class=”comkey”>$1</span>’) // 匹配注釋中的標(biāo)記
                         .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,
                      “<“: //g,
                      “<br>”: /n/g,
                      ” “: / /g,
                      ”  “: /t/g
                  };
              for (i in s) {
                  str = str.replace(s[i], i);
              }
              return str;
          }

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

      你們可以用下面的代碼進(jìn)行測(cè)試。

      代碼:

      復(fù)制代碼 代碼如下:
      <!doctype html>
      <html lang=”en”>
      <head>
          <meta charset=”UTF-8″>
          <title>test</title>
          <style>
          /* 高亮樣式 */
          *{font-size:12px;}
          code{word-break:break-all;}

          .com {color:#008000;} /* 注釋 */
          .comkey {color:#FFA500;} /* 注釋標(biāo)記 */
          .str {color:#808080;} /* 字符串 */
          .val {color:#000080;} /* true|false|null|undefined|NaN */
          .kwd {color:#000080;font:bold 12px ‘comic sans ms’, sans-serif;} /* 關(guān)鍵詞 */
          .obj {color:#000080;} /* 內(nèi)置對(duì)象 */
          .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 測(cè)試一下
       */
      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<1e3; i++) {
          var node = document.getElementById(“a”+i);
          arr.push(node);
      }

      function test () {
          return true;
      }
      test();

       

      (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 <= 7; i++) {
                      if (s = a[i]) {
                          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|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)置對(duì)象 obj
                                  return ‘<span class=”obj”>’ + s + ‘</span>’;
                              case 6: //數(shù)字 num
                                  return ‘<span class=”num”>’ + s + ‘</span>’;
                              case 7: //正則 reg
                                  return htmlEncode(a[0]).replace(s, ‘<span class=”reg”>’ + s + ‘</span>’);
                          }
                      }
                  }
                  return htmlEncode(a[0]);
              });
              code = code.replace(/(?:s**s*|(?: )**(?: )*)(@w+)b/g, ‘ * <span class=”comkey”>$1</span>’) // 匹配注釋中的標(biāo)記
                         .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,
                      “<“: /</g,
                      “>”: />/g,
                      “<br>”: /n/g,
                      ” “: / /g,
                      ”  “: /t/g
                  };
              for (i in s) {
                  str = str.replace(s[i], i);
              }
              return str;
          }

          window.prettify = prettify;
      })(window);
      </code>

      <script>
      (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 <= 7; i++) {
                      if (s = a[i]) {
                          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|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)置對(duì)象 obj
                                  return ‘<span class=”obj”>’ + s + ‘</span>’;
                              case 6: //數(shù)字 num
                                  return ‘<span class=”num”>’ + s + ‘</span>’;
                              case 7: //正則 reg
                                  return htmlEncode(a[0]).replace(s, ‘<span class=”reg”>’ + s + ‘</span>’);
                          }
                      }
                  }
                  return htmlEncode(a[0]);
              });
              code = code.replace(/(?:s**s*|(?: )**(?: )*)(@w+)b/g, ‘ * <span class=”comkey”>$1</span>’) // 匹配注釋中的標(biāo)記
                         .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,
                      “<“: /</g,
                      “>”: />/g,
                      “<br>”: /n/g,
                      ” “: / /g,
                      ”  “: /t/g
                  };
              for (i in s) {
                  str = str.replace(s[i], i);
              }
              return str;
          }

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

      var code = document.getElementById(“regdemon”);
      code.innerHTML = prettify(code);
      </script>
      </body>
      </html>

      差不多結(jié)合了 小胡子哥 和 次碳酸鈷 兩個(gè)思路的結(jié)果,現(xiàn)在比較完善了。
      兼容性什么的還沒測(cè)試,也沒必要測(cè)試了,我也沒打算自己寫各種語法的高亮,太TM累了。。

      贊(0)
      分享到: 更多 (0)
      網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)