regexp.js 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. /**
  2. * 注册命名空间:baidu.regexp
  3. */
  4. baidu.namespace.register("baidu.regexp");
  5. /**
  6. * 自适应高度的jquery插件
  7. */
  8. $.fn.extend({
  9. textareaAutoHeight:function (options) {
  10. this._options = {
  11. minHeight:0,
  12. maxHeight:100000
  13. };
  14. this.init = function () {
  15. for (var p in options) {
  16. this._options[p] = options[p];
  17. }
  18. if (this._options.minHeight == 0) {
  19. this._options.minHeight = parseFloat($(this).height());
  20. }
  21. for (var p in this._options) {
  22. if ($(this).attr(p) == null) {
  23. $(this).attr(p, this._options[p]);
  24. }
  25. }
  26. $(this).keyup(this.resetHeight).change(this.resetHeight)
  27. .focus(this.resetHeight);
  28. }
  29. this.resetHeight = function () {
  30. var _minHeight = parseFloat($(this).attr("minHeight"));
  31. var _maxHeight = parseFloat($(this).attr("maxHeight"));
  32. if (!$.browser.msie) {
  33. $(this).height(0);
  34. }
  35. var h = parseFloat(this.scrollHeight);
  36. h = h < _minHeight ? _minHeight :
  37. h > _maxHeight ? _maxHeight : h;
  38. $(this).height(h).scrollTop(h);
  39. if (h >= _maxHeight) {
  40. $(this).css("overflow-y", "scroll");
  41. }
  42. else {
  43. $(this).css("overflow-y", "hidden");
  44. }
  45. }
  46. this.init();
  47. }
  48. });
  49. baidu.regexp = (function () {
  50. "use strict";
  51. var regElm, srcElm, rstElm, rstCount, srcBackgroundElm, srcWrapperElm, regListElm;
  52. var ID_PREFIX = 'tmp_id_';
  53. var TAG_MATCHED = 'b';
  54. var TAG_NOT_MATCHED = 'i';
  55. var TR_ID_PREFIX = 'tr_' + ID_PREFIX;
  56. var _getRegExp = function (regTxt) {
  57. try {
  58. return new Function('return ' + regTxt)();
  59. } catch (e) {
  60. return null;
  61. }
  62. }
  63. var _buildTable = function (rstArray) {
  64. var tbl = ["<table class='table table-bordered table-striped table-condensed table-hover'>"];
  65. tbl.push('<tr class="active"><th class="num">序号</th><th>匹配结果</th><th>在原字符串中的位置</th></tr>')
  66. $.each(rstArray, function (i, item) {
  67. tbl.push('<tr id="' + TR_ID_PREFIX + item.index + '" data-index="' + item.index + '">');
  68. tbl.push('<td class="num">' + (i + 1) + '</td>'
  69. + '<td class="content">' + item.text + '</td>'
  70. + '<td class="index">' + item.index + '</td>');
  71. tbl.push('</tr>');
  72. });
  73. tbl.push('</table>');
  74. return tbl.join('');
  75. };
  76. var _createTag = function (type, item) {
  77. var tags = [];
  78. for (var i = 0, len = item.text.length; i < len; i++) {
  79. tags.push('<' + type + ' data-id="' + ID_PREFIX + item.index + '">'
  80. + item.text.charAt(i) + '</' + type + '>');
  81. }
  82. return tags.join('');
  83. }
  84. var _blinkHighlight = function () {
  85. $('tr[id^=' + TR_ID_PREFIX + ']').click(function (e) {
  86. var index = $(this).attr('data-index');
  87. var tags = $(TAG_MATCHED + '[data-id=' + ID_PREFIX + index + ']');
  88. tags.animate({
  89. opacity:0
  90. }, 200).delay().animate({
  91. opacity:1
  92. }, 200).delay().animate({
  93. opacity:0
  94. }, 200).delay().animate({
  95. opacity:1
  96. }, 200);
  97. });
  98. };
  99. var _highlight = function (srcText, rstArray) {
  100. if (!srcText) {
  101. srcBackgroundElm.html('');
  102. return;
  103. }
  104. var hl = [];
  105. var preIndex = 0;
  106. $.each(rstArray, function (i, item) {
  107. if (i == 0) {
  108. if (item.index == 0) {
  109. hl.push(_createTag(TAG_MATCHED, item));
  110. } else {
  111. hl.push(_createTag(TAG_NOT_MATCHED, {
  112. index:0,
  113. text:srcText.substring(0, item.index)
  114. }));
  115. hl.push(_createTag(TAG_MATCHED, item));
  116. }
  117. } else {
  118. preIndex = rstArray[i - 1].index + rstArray[i - 1].text.length;
  119. hl.push(_createTag(TAG_NOT_MATCHED, {
  120. index:preIndex,
  121. text:srcText.substring(preIndex, item.index)
  122. }));
  123. hl.push(_createTag(TAG_MATCHED, item));
  124. }
  125. });
  126. srcBackgroundElm.html(hl.join(''));
  127. _blinkHighlight();
  128. };
  129. var _emptyTable = function (message) {
  130. var tbl = ["<table class='table table-bordered table-striped table-condensed table-hover'>"];
  131. tbl.push('<tr class="active"><th class="num">序号</th><th>匹配结果</th></tr>');
  132. tbl.push('<tr><td colspan="2">' + message + '</td></tr>');
  133. tbl.push('</table>')
  134. return tbl.join('');
  135. };
  136. var _dealRegMatch = function (e) {
  137. srcWrapperElm.height(srcElm.height() + 24);
  138. var regTxt = regElm.val().trim();
  139. var srcTxt = srcElm.val().trim();
  140. if (!regTxt || !srcTxt) {
  141. rstElm.html(_emptyTable('不能匹配'));
  142. rstCount.html('0个');
  143. _highlight();
  144. } else {
  145. var reg = _getRegExp(regTxt);
  146. if (!reg || !reg instanceof RegExp) {
  147. rstElm.html(_emptyTable('正则表达式错误!'));
  148. rstCount.html('0个');
  149. _highlight();
  150. return;
  151. }
  152. var rst = [];
  153. // 用字符串的replace方法来找到匹配目标在元字符串中的准确位置
  154. srcTxt.replace(reg, function () {
  155. var matchedTxt = arguments[0];
  156. var txtIndex = arguments[arguments.length - 2];
  157. rst.push({
  158. text:matchedTxt,
  159. index:txtIndex
  160. });
  161. });
  162. if (!rst || !rst.length) {
  163. rstElm.html(_emptyTable('不能匹配'));
  164. rstCount.html('0个');
  165. _highlight();
  166. } else {
  167. rstElm.html(_buildTable(rst));
  168. rstCount.html(rst.length + '个');
  169. _highlight(srcElm.val(), rst);
  170. }
  171. }
  172. };
  173. var _init = function () {
  174. $(function () {
  175. regElm = $('#regText');
  176. srcElm = $('#srcCode');
  177. srcBackgroundElm = $('#srcBackground');
  178. srcWrapperElm = $('#srcWrapper');
  179. rstElm = $('#rstCode').html(_emptyTable('暂无输入'));
  180. rstCount = $('#rstCount');
  181. regListElm = $('#regList');
  182. // 输入框自适应高度
  183. regElm.textareaAutoHeight({minHeight:34});
  184. srcElm.textareaAutoHeight({minHeight:50});
  185. srcBackgroundElm.textareaAutoHeight({minHeight:50});
  186. // 监听两个输入框的按键、paste、change事件
  187. $('#regText,#srcCode').keyup(_dealRegMatch).change(_dealRegMatch)
  188. .bind('paste', _dealRegMatch);
  189. regListElm.change(function (e) {
  190. var reg = $(this).val();
  191. var regTipElm = $('#regTip');
  192. regElm.val(reg);
  193. if (!reg) {
  194. regTipElm.hide();
  195. } else {
  196. regTipElm.show();
  197. }
  198. });
  199. });
  200. };
  201. return {
  202. init:_init
  203. };
  204. })();
  205. baidu.regexp.init();