本人之前开发的正则表达式工具

来源:互联网 发布:林建岳王祖贤 知乎 编辑:程序博客网 时间:2024/05/16 18:40
<!--Author: shoshSite: http://www.wscxy.comUser Guide:  http://www.wscxy.com/shosh/article.asp?id=105QQ:  12472727610/09/09.1、\r不在可以高亮,以防止高亮换行(在最右边时为了高亮\r而添加空格可能导致换行而导致高亮不匹配)2、不能高亮的匹配同样占用颜色计数10/02/20.1、Fix Bug: 当最后有换行时,高亮位置不正确2、让高亮的HTML无误生成,这样即使待处理文本包含各种复杂HTML标记也不会出错。3、修正之前引入的提示错误:结果提示框中的 未按空格显示09/08/08.1、增加显示子匹配功能2、高亮不可见但是可选中字符\r3、修正一个很隐含的选中功能的BUG,选中区域有可能包含字符\n,但是不能把\n计算到长度中,否则下一次选择会偏移过多09/08/07.1、增加高亮匹配功能,使用3个区分,且有总开关控制2、修正非全局模式下的匹配次数计算错误(match[1-n]为子匹配) 3、增加替换函数输入区域的水平滚动功能,并有开关控制09/08/06.1、增强对替换函数的错误捕捉功能,并使前期检查忽略函数参数个数相关的错误2、防止对替换函数的语法预检查时出现alert,prompt,comfirm等对话框09/08/05.1、允许输入Tab2、允许使用函数替换, 并做了防错处理,会提示错误描述已知BUG:1、循环查找的替换函数中的obj为选中的字符串,而非原来的字符串,pos也是相对与选中的字符串(往往是0),直接替换和预览替换结果不会有这个BUG。这个是循环(单个)查找原理所致,无法修正。09/07/08.1、修正HTML代码的正确预览的Bug,同时为修正该Bug,顺便让“计算匹配次数”下的分隔符使用黑色粗体(本来无法指定颜色),这样分隔符更加显眼2、允许输入框中或替换后中出现的HTML转义字符按照转义前预览,如  在预览是显示为 而不是' ' 或 '[ES]'3、添加单个替换功能4、允许用户选择预览方式5、添加更新说明,所以之前的更新记录不全不足:1、无法以特殊方法(如字体颜色、加粗等)显示预览中的替换内容(按照目前的设计,似乎无法实现)2、无法在使用单个替换功能后继续循环查找和单个替换,必须重新开始(如果不重新开始肯定会有bug,因为源改变后,匹配情况随之发生改变,所以基本上也没有解决办法的)09/07/07.1、已经可以让查询表达式输入框以及替换表达式和直接在代码中构造的字符串具有同等的效果(主要考虑某些特殊字符的问题,如\n\n\\等)2、已经有两种预览显示方式,其中不可见字符已经使用一定颜色的字符串代替09/07/03.1、初始版本,实现基本功能,但是对于特殊字符的处理尚未考虑--><HTML><HEAD><title>正则表达式工具(http://www.wscxy.com by Shosh)V2010.09.08</title> <META HTTP-EQUIV="Content-Type" CONTENT="text/html;charset=gb2312"><style>#taResult{text-align:left; width:100%; height:140px;overflow-y: scroll; font-weight:normal; font-size:9pt; border:silver 1px inset; padding:2px; word-wrap:break-word; word-break:break-all;}#smartBgField{position:relative;width:100%;height:140px;padding:0px}#smartBgField PRE,TEXTAREA{FONT: 100% "courier new",monospace; font-size:9pt; WIDTH: 100%;height:140px;word-wrap:break-word; word-break:normal;overflow-x:hidden;overflow-y: scroll;text-align:left;margin:0px;border:silver 1px inset; padding:2px;}#smartBgField PRE{z-index:1;background:white; color:white}#smartBgField TEXTAREA{BACKGROUND:transparent none repeat scroll 0% 0%; z-index:2;position:absolute; left:0px; top: 0px; color:black}#smartBgField PRE B,U,I{background:#FFFFFF; COLOR: #FFFFFF; FONT-WEIGHT: normal; FONT-STYLE: normal; TEXT-DECORATION: none}#smartBgField PRE B{background:#b688cf; color:#b688cf}#smartBgField PRE U{background:#efba4a; color:#efba4a}#smartBgField PRE I{background:#66c83f; color:#66c83f}#taSource, #preSource{position:absolute; left:0px; top: 0px;}</style></HEAD><body style="margin:0px;padding:4px 8px 0px 8px"><center><div style="FONT-WEIGHT:bold;FONT-SIZE:11pt;WIDTH:90%px;TEXT-ALIGN:center;padding:0px;margin:0px"><h2>正则表达式执行工具 <a href="http://www.wscxy.com" style="font-size:9pt">作者首页</a><a href="http://www.wscxy.com/shosh/article.asp?id=105" style="font-size:9pt;" target="_blank">使用说明</a></h2><div id="smartBgField" style="width:100%;height:140px"><textarea id='taSource' onchange="invalidateSelection()">请在这里输入待测/待处理文本例子:查找所有单词中含有相同元音字母(a/e/i/o/u)的单词,替换时在该单词两侧用匹配到的元音字母包起来。This tool is designed and implemented by Shosh, whose qq number is 124727276 and whose home page is http://www.wscxy.com.You can test your regular expression when you are trying to make it with this tool, and I believe it will help you much.You can also just deal with your string using some specific regular expressions and get the useful result back.OK, just enjoy it.This text is just for test with the default regular expression. You can change them to take more tests.</textarea><pre id="preSource"></pre></div>查询表达式:<input id="txtMatchPattern" type="text" size="70" value="(\b\w*([aeiou]+)\w*\2\w*\b)" onchange="invalidateSelection()"><br><div><button onclick="swtichRepPtn()">[切换]替换式</button><span style="position:relative"><input style="z-index:1" id="txtRplcPattern" type="text" size="70" value="[$2]$1[/$2]"><div id="divScrollX" style="position:absolute;left:0px;top:0px;visibility:hidden"><input type="checkbox" id="cRepFunScrollX"><label for="cRepFunScrollX" style="font-weight:normal">水平滚动</label></div></span><textarea id="taRplcPattern" rows='8' cols='82' onchange="invalidateSelection()" style="display:none">//Function Body(专家模式,使用替换函数,如果不了解原理,请按“[切换]替换式”按钮使用普通字符串替换)var match = arguments[0]; //匹配得到的字符串var pos = arguments[arguments.length - 2]; //在原字符串中的匹配位置 var obj = arguments[arguments.length - 1]; //原字符串对象if (arguments.length < 125) //保护if里的代码不被检测而导致全局数据变化isNaN(window.gValue) ? window.gValue = 0 : window.gValue++; //全局变量请使用window.xxxx//return window.gValue + ":" + match;return match.toLowerCase();//return match.toUpperCase();</textarea></div><input type="checkbox" checked id="cIgnoreCase"><label for="cIgnoreCase">忽略大小写</label><input type="checkbox" checked id="cGlobal"><label for="cGlobal">全局匹配</label><input type="checkbox" checked id="cMultiline"><label for="cMultiline">多行匹配</label> <span style="font-weight:normal">¤ 预览方法:</span><select id="selShowMethodMask"><option value="1" selected>方法一:蓝色显示可见字符</option><option value="2">方法二:灰色显示所有字符</option><option value="3">同时使用方法一和方法二</option></select><input type="checkbox" checked id="cHighlightMatches"><label style="font-weight:normal" for="cHighlightMatches">高亮匹配</label><input type="button" value="新窗口查看" id="btnViewInNewWin"><input type="checkbox" id="cRefreshNewWin"><label style="font-weight:normal" for="cRefreshNewWin">同步更新</label><br><input type="button" id="btnCount" value="匹配次数"><input type="checkbox" title="仅在全局匹配时生效" id="cGetMatches"><label style="font-weight:normal" title="仅在全局匹配时生效" for="cGetMatches">获取匹配</label><input type="button" id="btnSchSel" value="循环查找"><input type="button" id="btnSchRplRslt" value="预览结果"><input type="button" id="btnSchRplSrc" value="直接替换"><input type="checkbox" id="cRepeatRpl"><label style="font-weight:normal" for="cRepeatRpl">重复替换</label><input type="button" id="btnRepTimer100" value="0.1s" onclick="setRepTimer(this, 100)"><input type="button" id="btnRepTimer500" value="0.5s" onclick="setRepTimer(this, 500)"><input type="button" id="btnRepTimer1000" value="1s" disabled="true" onclick="setRepTimer(this, 1000)"><input type="button" id="btnRepTimer2000" value="2s" onclick="setRepTimer(this, 2000)"><input type="button" id="btnRepTimer5000" value="5s" onclick="setRepTimer(this, 5000)"><br><pre id="taResult">预览区域</pre><br><div id="shoBackupFunctions" style="vertical-align:top;display:inline">内置功能:<select id="shoRegOptions" size=5></select><textarea readonly id="shoRegCommnet" style="width:400px; height:80px"></textarea></div></div></center></body><script language="JavaScript"><!--var gWinResultViewer = null;var gReplaceTime = 0;var gRepeaterTimer = 1000;window.onunload = function(){if (gWinResultViewer){try{gWinResultViewer.window.opener = null;gWinResultViewer.close();}catch (e){}gWinResultViewer = null;}}function updateResultWin(){if (gWinResultViewer){try{gWinResultViewer.window.document.open();gWinResultViewer.window.document.write("<HTML><HEAD><title>正则表达式工具浏览窗口</title><META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text\/html;charset=gb2312\">"    + "<style>PRE{z-index:1; color:black; word-wrap:break-word; word-break:break-all;FONT: 100% \"courier new\",monospace; font-size:9pt; WIDTH: 100%; height:100%; overflow-x:hidden;overflow-y: scroll;text-align:left;margin:0px;border:silver 1px inset; padding:2px;}\n"+ "PRE B,U,I{background:#FFFFFF; FONT-WEIGHT: normal; FONT-STYLE: normal; TEXT-DECORATION: none}\n"+ "PRE B{background:#b688cf;}\n"+ "PRE U{background:#efba4a;}\n"+ "PRE I{background:#66c83f;}\n"+ "body{margin:0px; padding:2px}\n"+ "<\/style><\/head><body>" + preSource.outerHTML + "<\/body><\/html>");gWinResultViewer.window.document.close();if (!cRefreshNewWin.checked){gWinResultViewer.focus();}}catch (e){//try to close the windowtry{gWinResultViewer.window.opener = null;gWinResultViewer.close();}catch (e){}gWinResultViewer = null;}}}function openViewerWindow(bLastTime){if (!gWinResultViewer){gWinResultViewer = window.open("about:blank", "", "resizable=yes,locationbar=no,status=no,direction=no,width=800,height=400,top=0,left=0");}updateResultWin();//反检一次if (!bLastTime && null == gWinResultViewer){openViewerWindow(true); //只在这里使用参数true调用,防止意外死循环}}btnViewInNewWin.onclick = openViewerWindow;function setRepTimer(obj, val){btnRepTimer100.disabled = false;btnRepTimer500.disabled = false;btnRepTimer1000.disabled = false;btnRepTimer2000.disabled = false;btnRepTimer5000.disabled = false;gRepeaterTimer = val;obj.disabled = true;}function RegExpStruct(name, findExp, repExp, caseFlags, comment){this.name = name;this.findExp = findExp;this.replaceExp = repExp;this.caseFlags = 0;//caseFlags = caseFlags.toLowerCase();//if (caseFlags.indexOf("i") >= 0)if (/i/i.test(caseFlags))this.caseFlags |= 0x04;//if (caseFlags.indexOf("g") >= 0)if (/g/i.test(caseFlags))this.caseFlags |= 0x02;//if (caseFlags.indexOf("m") >= 0)if (/m/i.test(caseFlags))this.caseFlags |= 0x01;this.comment = comment;}//common regular expressionsvar shoComRegExpArr = [new RegExpStruct("重复原音字母单词", "(\\b\\w*([aeiou]+)\\w*\\2\\w*\\b)", "$1", "igm", "[功能]查找含多个相同原音字母的单词"),new RegExpStruct("格式化Warning", "^\\d+\\s+warning.*[\/\\\\](target[\/\\\\].*?)\\s*$", "$1", "gm", "[操作]直接替换一次即可。"),new RegExpStruct("删除warning中的引号", "‘|\"|\'|`|”", "", "gm", "按直接替换按钮一次即可"),new RegExpStruct("过滤重复行", "(^.*\\w[^\\n]*\\n)([\\w|\\W]*?)^\\1+", "$1$2", "gm", "[操作]重复按直接替换按钮,最后一行需有换行符;删除时优先删除后面重复的行内容而保留最前面出现重复现象的行内容。")//,new RegExpStruct("过滤重复行", "(^[^\\r\\n]+)([\\w|\\W]*?)^\\1+$", "$1$2", "gm", "[操作]重复按直接替换按钮,最后一行需有换行符;删除时优先删除后面重复的行内容而保留最前面出现重复现象的行内容。"),new RegExpStruct("过滤内存未泄露信息", "\\[(0x[\\d|A-F]+)\\(\\d+\\)\\].*(\\n[\\w\\W]*)\\[\\1\\].*", "$2", "gm", "[操作]直接按替换按钮,直到找不到新匹配。"),new RegExpStruct("过滤内存未泄露信息(删除换行)", "\\[(0x[\\d|A-F]+)\\(\\d+\\)\\].*\\n([\\w\\W]*)\\[\\1\\].*\\n", "$2", "gm", "[操作]直接按替换按钮,直到找不到新匹配。"),new RegExpStruct("过滤重复单词(保留一份)", "(\\b(\\w+)\\b[\\w\\W]*)\\b(\\2)\\b", "$1", "gm", "[操作]连续按直接替换按钮直到找不到匹配。\n该方法会保留匹配到的第一份单词,删除所有后续重复的单词。"),new RegExpStruct("过滤重复单词(不保留)", "\\b(\\w+)\\b([\\w\\W]*)\\b(\\1)\\b", "$2", "gm", "[操作]连续按直接替换按钮直到找不到匹配。\n该方法会删除所有匹配到的单词,但是当只有奇数个相同单词时,会有一个单词不会被消去。"),new RegExpStruct("过滤多余空行和行两端空格", "(\\s*\\r\\n\\s*)+", "\\r\\n", "gm", "[功能]过滤多余空行和行两端空格。"),new RegExpStruct("删除行两端空格", "^\\s*(.*?)\\s*$", "$1", "gm", "[操作]按直接替换按钮,中文空格不会被删除,英文空格和Tab等都会被删除。"),new RegExpStruct("每行按字母循环滚动", "([^\\r\\n])([^\\r\\n]*)", "$2$1", "gm", "[操作]重复按直接替换按钮,若选中重复替换,则有动画效果(滚动单元为一个字符)。"),new RegExpStruct("RED数据all", "(ulItemIndex\\[(0x[\\da-f]+)\\]\\s+ulSubItemIndex\\[\\s*(\\d+)\\]\\s+ulRetreiveFunc\\[(0x[\\da-f]+)\\][\\w\\W]*?)? MaxSize\\[(\\d+)\\],AveSize\\[(\\d+)\\],NotifyMaxCnt\\[(\\d+)\\],ulNotifyAveCnt\\[(\\d+)\\],ulNotifyMaxFailCnt\\[(\\d+)\\],ulNotifyTolFailCnt\\[(\\d+)\\],ulRetrieveMaxCnt\\[(\\d+)\\],ulRetrieveAveCnt\\[(\\d+)\\]", "$2\\t$3\\t$4\\t$5\\t$6\\t$7\\t$8\\t$9\\t$10\\t$11\\t$12", "gm", "red data。"),new RegExpStruct("获取CPU占用率信息", "^\\s*([\\.\\w]+)\\s*(\\d+\\s*){4}(\\d+)$", "$1\\t$3", "gm", "先获取匹配再直接替换,然后就可以粘贴到excel中处理啦~~~"),new RegExpStruct("Valgrind检查结果分析", "^\\d+.*\\n==.*(:\\d+).*\\n(==.*\\n?)*", "", "gm", "使用该工具前先进行“过滤多余空行和行两端空格”处理。选择本匹配模式后,在冒号前输入文件名可按文件顺序进行排查已防止重复工作,使用循环查找与替换可获得较好效果。该方法同时还会过滤最后检查发生在库里的记录。")];function optionSelected(){var objSel = document.getElementById("shoRegOptions");var i = objSel.options.selectedIndex;if (i < 0)return;document.getElementById("txtMatchPattern").value = shoComRegExpArr[i].findExp;document.getElementById("txtRplcPattern").value = shoComRegExpArr[i].replaceExp;document.getElementById("cIgnoreCase").checked = shoComRegExpArr[i].caseFlags & 0x04;document.getElementById("cGlobal").checked = shoComRegExpArr[i].caseFlags & 0x02;document.getElementById("cMultiline").checked = shoComRegExpArr[i].caseFlags & 0x01;document.getElementById("shoRegCommnet").value = shoComRegExpArr[i].name + ":\r\n    " + shoComRegExpArr[i].comment;highLightSource();}function initComRegExpSelectOptions(){var i;var objSel = document.getElementById("shoRegOptions");for (i = 0; i < shoComRegExpArr.length; i++){objSel.options.add(new Option(shoComRegExpArr[i].name, "shosh"));}objSel.options.selectedIndex = 0;objSel.onchange = optionSelected;optionSelected();}//highlight codefunction adjustScroll(){preSource.scrollTop = taSource.scrollTop;preSource.scrollLeft = taSource.scrollLeft;}taSource.onscroll = adjustScroll;var stylizerHead = ["<B>", "<U>", "<I>"];var stylizerTail = ["<\/B>", "<\/U>", "<\/I>"];function highLightSource(){if (!cHighlightMatches.checked)return;var reg = null;try{reg = new RegExp(txtMatchPattern.value, getMode());} catch (e){}if (null == reg){preSource.outerHTML = "<pre id=\"preSource\">" + taSource.value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">") + "</pre>";}else{var i = 0;var lastPos = 0;var repOut = taSource.value.replace(/\r/g, "").replace(/^(\n*)[\w\W]*/, "$1").replace(/\n/g, " <br>");var srcString = taSource.value.replace(/\r/g, "").replace(/^\n+/, "");//.replace(/\n+$/, "");srcString.replace(reg, function(){var match = arguments[0];var pos = arguments[arguments.length - 2];repOut += srcString.substring(lastPos, pos).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");i = ++i % stylizerHead.length;if ("" != match.replace(/\n/g, "")){//replace(/\r/g, " ") below is to make \r highlightablerepOut += stylizerHead[i] + match.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">")/*.replace(/\r/g, " ")*/ + stylizerTail[i];}else{//just keep \n(s), no need to convert <br>(s)repOut += match;//.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");}lastPos = pos + match.length;});var tail = srcString.substring(lastPos, srcString.length);repOut += tail.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">"); //add tail//let the hight of preSource is bigger than this of taSourcepreSource.outerHTML = "<pre id=\"preSource\">" + repOut + "<br> <br> <br> <\/pre>";}adjustScroll();if (cRefreshNewWin.checked){updateResultWin();}}cIgnoreCase.onclick = highLightSource;cGlobal.onclick = highLightSource;cMultiline.onclick = highLightSource;taSource.onpaste = highLightSource;taSource.onkeyup = highLightSource;taSource.oncut = highLightSource;taSource.onchange = highLightSource;txtMatchPattern.onkeyup = highLightSource;txtMatchPattern.oncut = highLightSource;txtMatchPattern.onpaste = highLightSource;cHighlightMatches.onclick = function(){if (this.checked)highLightSource();elsepreSource.outerHTML = "<pre id=\"preSource\">" + taSource.value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">") + "</pre>";};preSource.onselectstart = function(){return false;}//UI control codefunction swtichRepPtn(){if ("none" == taRplcPattern.style.display){taRplcPattern.style.display = "inline";txtRplcPattern.style.visibility = "hidden";shoBackupFunctions.style.display = "none";//checkbox : scrollxdivScrollX.style.visibility = "visible";}else{taRplcPattern.style.display = "none";txtRplcPattern.style.visibility = "visible";shoBackupFunctions.style.display = "inline";//checkbox : scrollxdivScrollX.style.visibility = "hidden";}}function cRepFunScrollX.onclick(){with (taRplcPattern.style){wordWrap = cRepFunScrollX.checked ? "normal" : "break-word";overflowX = cRepFunScrollX.checked ? "scroll" : "hidden";}}function editTab(){var code, sel, tmp, r;var tabs = "";var returnValue = false;var who = event.srcElement;sel = who.document.selection.createRange();r = who.createTextRange();switch (event.keyCode){case 9:if (sel.getClientRects().length > 1){var poz=event.srcElement.scrollLeft;event.srcElement.scrollLeft=0;code = sel.text;tmp = sel.duplicate();tmp.moveToPoint(r.getBoundingClientRect().left, sel.getClientRects()[0].top);sel.setEndPoint("startToStart", tmp);if(event.shiftKey){sel.text = sel.text.replace(/\t/g, "");sel.text = sel.text.replace(/\n/g, "\r");code=code.replace(/\t/g,"");code = code.replace(/\n/g, "\r");if(r.findText(code))r.select();}else{sel.text = "\t"+sel.text.replace(/\n/g, "\r\t");code = "\t"+code.replace(/\n/g, "\r\t");if(!r.findText(code))r.findText(code.replace(/\t/, ""));r.select();}who.scrollLeft=poz;}else{sel.text = "\t";sel.select();}break;case 13:tmp = sel.duplicate();tmp.moveToPoint(r.getBoundingClientRect().left, sel.getClientRects()[0].top);tmp.setEndPoint("endToEnd", sel);for (var i=0; tmp.text.match(/^[\t]+/g) && i<tmp.text.match(/^[\t]+/g)[0].length; i++)tabs += "\t";sel.text = "\n"+tabs;sel.select();break;default:returnValue = true;break;}return returnValue;}function makeTextAreaTabKey(){var taArr = document.getElementsByTagName("TEXTAREA");if (null != taArr){for (var i = taArr.length - 1; i >= 0; i--)taArr[i].onkeydown = editTab;}}//main codefunction String.prototype.raw(){var str = this.toString();if ("" != str){str = str.replace(/\\([\'\"\\ntrfb])/ig, function(match, $1, pos, obj){switch($1){case '\'': return "\'";case '\"': return "\"";case '\\': return "\\";case 'n': return "\n";case 'r': return "\r";case 't': return "\t";case 'f': return "\f";case 'b': return "\b"; //here \b is not non-wordboundary, but \010(0x08)default: return match;}});}return str;}function String.prototype.toVisible(bAvoidHtml){//control how to replace some special chars and its style//[ES]: English Space//[CS]: Chinese Spacevar spaceColor = "#AAAAFF";var str = this;if (bAvoidHtml){str = str.replace(/&/g, "&"); //avoid special HTML words shown as its real meaning, such as < &...str = str.replace(/</g, "<").replace(/>/g, ">") //avoid HTML code}return str.replace(/ /g, "[ES]".fontcolor(spaceColor)) //this must be in this line, considering [English Space].replace(/ /g,"[CS]".fontcolor(spaceColor)).replace(/\r/g, "[\\r]".fontcolor(spaceColor)).replace(/\n/g, "[\\n]".fontcolor(spaceColor)).replace(/\t/g, "[\\t]".fontcolor(spaceColor))//\b is special in regular expression, so we can not use \b but \010 because the ascii code of the char \b is 0x08.replace(/\010/g, "[\\b]".fontcolor(spaceColor)).replace(/\f/g, "[\\f]".fontcolor(spaceColor));}function String.prototype.htmlEncode(){return this.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/ /g, " ")//we use " <br>" as a new line for "<br>" cannot make new lines as we wish sometimes..replace(/\r\n/g, " <br>").replace(/\r/g, " <br>").replace(/\n/g, " <br>").replace(/\t/g, "        ");}var ALERT = CONFIRM = PROMPT = function(){};function getReplaceValue(){if ("none" != taRplcPattern.style.display){//with functiontry{//try to find out syntax and some runtime errors.var source = "It is desinged by Shosh whose site is http://www.wscxy.com";var finder = "Shosh";var s = "";var testFunBody = taRplcPattern.value.replace(/\b(alert|confirm|prompt)\b/g, function(){return arguments[0].toUpperCase();});//give the function enough parameters to avoid checking arguments.length new Function(testFunBody).call(null, finder, s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s, source.indexOf(finder), source);//the new function will find out runtime errorreturn new Function("try{\n" + taRplcPattern.value + "\n}catch(e){\n"+ "alert(\'在您使用的替换函数中发现如下运行时错误,请更正后重试:\\n--错误描述:[\'"+ "+ e.description + \']\\n--错误码:[\' + (e.number & 0xFFFF) + \']\')}");}catch (e){alert("在您使用的替换函数中发现如下错误,请更正后重试:\n--错误描述:["+ e.description + "]\n--错误码:[" + (e.number & 0xFFFF) + "]");return new Function(taRplcPattern.defaultValue);}}//with simple stringreturn txtRplcPattern.value.raw();}function getShowMethodMask(){return parseInt(selShowMethodMask.options[selShowMethodMask.selectedIndex].value);}function setSourceValue(text){taSource.value = text;highLightSource();}function htmlResult(html, bAdd){if (bAdd)taResult.innerHTML += html;elsetaResult.innerHTML = html;}function addResult(text, color){if (null == color){taResult.innerHTML += text.htmlEncode();}else{taResult.innerHTML += text.htmlEncode().fontcolor(color);}}function setResult(text, color){if (null == color){taResult.innerHTML = text.htmlEncode();}else{taResult.innerHTML = text.htmlEncode().fontcolor(color);}}function getMode(){var mode = "";if (cIgnoreCase.checked)mode += "i";if (cGlobal.checked)mode += "g";if (cMultiline.checked)mode += "m";return mode;}function isRegExpEmpty(){    if(txtMatchPattern.value == "")    {setResult("请输入[查询表达式]!", "red");txtMatchPattern.focus();return true;    }return false;}function getRegExp(){var s = null;if (!isRegExpEmpty()){try{s =  new RegExp(txtMatchPattern.value, getMode());}catch (e){var errstr = "正则表达式[ " + txtMatchPattern.value + " ]错误!\n错误描述:";htmlResult("正则表达式[".bold().fontcolor("red"), false);htmlResult(txtMatchPattern.value.htmlEncode().fontcolor("blue"), true);htmlResult("]错误!<br>错误描述:".bold().fontcolor("red"), true);htmlResult(e.description.fontcolor("red"), true);alert(errstr + e.description);}}return s;}var srcTemp = ""; //backup the source, var gOneRepTimes = 0; //static for btnSchRplSrc.onclick(), used only by btnSchRplSrc.onclick()function btnSchRplSrc.onclick(){setResult("正在执行替换任务,请稍候……", "#FFAA00");var s = getRegExp();if (null == s)return;srcTemp = taSource.value;setSourceValue(srcTemp.replace(s, getReplaceValue()));setResult("替换完成,结果见上面的输入文本框。\n", "#006600");htmlResult("<button onclick='undoReplaceAction()'>撤消替换操作<\/button>"+ "<button onclick='copyResult()'>复制替换结果<\/button>", true);invalidateSelection(); //make selection invalidationbtnSchRplSrc.value = "直接替换[" + (++gReplaceTime) + "]";if (cRepeatRpl.checked){//alert(gReplaceTime);//alert(s.test(srcTemp));//if (eval(s.test(srcTemp))){gOneRepTimes++;setTimeout("if (cRepeatRpl.checked){btnSchRplSrc.click();}", gRepeaterTimer);}//else{//alert("已经完成所有替换!\n有效替换共 " + gOneRepTimes + " 次。");//gOneRepTimes = 0;}}}function copyResult(){try{window.clipboardData.setData("text", taSource.value);setResult("已经将替换结果复制到剪切板。\n", "#006600");htmlResult("<button onclick='undoReplaceAction()'>撤消替换操作<\/button>", true);}catch (e){setResult("无法自动复制,请手动复制。\n", "#AA0000");htmlResult("<button onclick='undoReplaceAction()'>撤消替换操作<\/button>", true);taSource.focus();taSource.select();}}function btnSchRplRslt.onclick(){setResult("正在执行替换任务,请稍候……", "#FFAA00");    var s = getRegExp();if (null == s)return;var methodMask = getShowMethodMask();var rsltText = "";if (methodMask & 0x01) //method 1: only show visible chars{//i have no idea to mark replaced strings.rsltText = taSource.value.replace(s, getReplaceValue());htmlResult(rsltText.htmlEncode().fontcolor("blue") + "<br>");}if (methodMask & 0x02) //method 2:show both visible and invisible chars{//this will bold to show replaced strings.rsltText = taSource.value.replace(s, getReplaceValue());htmlResult(rsltText.toVisible(true).fontcolor("gray"), methodMask & 0x01);}}function btnCount.onclick(){setResult("正在执行计算任务,请稍候……", "#FFAA00");var s = getRegExp();if (null == s)return;var rslt = taSource.value.match(s);if (rslt){var methodMask = getShowMethodMask();if (cGlobal.checked || 1 == rslt.length) //全局或非全局且无子匹配{if (cGetMatches.checked){//备份srcTemp = taSource.value;for (i = rslt.length - 1; i >= 0; i--){rslt[i] = rslt[i].replace(/^\r*\n/, "").replace(/\r*\n$/, "");}setSourceValue(rslt.join("\n"));setResult("一共匹配 " + rslt.length + " 次,结果见上面的输入文本框。\n", "#006600");htmlResult("<button onclick='undoReplaceAction(\"已撤销获取匹配。\")'>撤消获取匹配<\/button>"+ "<button onclick='copyResult()'>复制匹配结果<\/button>", true);}else{htmlResult(("一共匹配 " + rslt.length + " 次。分别如下:").bold());}if (methodMask & 0x02) //show both visible and invisible chars{var rsltVisible = new Array(rslt.length);for (i = 0; i < rslt.length; i++){rsltVisible[i] = rslt[i].toVisible(true);}htmlResult("<br>" + rsltVisible.join(",".bold().fontcolor("black")).fontcolor("gray"), true);}if (methodMask & 0x01) //method 1: only show visible chars{addResult("\n" + rslt.join("\n"), "blue");}}else //非全局,且有子匹配{htmlResult(("一共匹配 1 次(非全局模式下),如下:").bold());if (methodMask & 0x02) //show both visible and invisible chars{htmlResult("<br>" + rslt[0].toVisible(true).fontcolor("gray"), true);}if (methodMask & 0x01) //method 1: only show visible chars{addResult("\n" + rslt[0], "blue");}//show child  matcheshtmlResult(("<hr>其中含有 " + (rslt.length - 1) + " 个子匹配,分别如下:").bold(), true);var rsltVisible = new Array(rslt.length - 1);if (methodMask & 0x02) //show both visible and invisible chars{for (i = 1; i < rslt.length; i++){rsltVisible[i - 1] = rslt[i].toVisible(true);}htmlResult("<br>" + rsltVisible.join(",".bold().fontcolor("black")).fontcolor("gray"), true);}if (methodMask & 0x01) //method 1: only show visible chars{for (i = 1; i < rslt.length; i++){rsltVisible[i - 1] = rslt[i];}addResult("\n" + rsltVisible.join("\n"), "blue");}}}else{htmlResult("没有找到匹配。".bold());}}var lastTimeTempResult = "";var selIndex = 0; //-1 (or any value that is minus) means it should restart to findvar srcTextRange = taSource.createTextRange();function btnSchSel.onclick(){setResult("正在执行搜索任务,请稍候……", "#FFAA00");    var s = getRegExp();if (null == s)return;var rslt = taSource.value.match(s);if (null == rslt){htmlResult("没有找到匹配。".bold());return;}if ((selIndex >= 0 && selIndex < rslt.length && cGlobal.checked) || ((!cGlobal.checked) && 0 == selIndex)){if ("" == rslt[selIndex]){lastTimeTempResult += "第 " + (++selIndex) + " 个匹配为空。\n";//this.onclick();if (selIndex < rslt.length){//try to find next match// use setTimeout instead of direct calling  to avoid stack overflowsetTimeout("btnSchSel.onclick();", 0);}else{//finish, jsut show result and reset the statussetResult(lastTimeTempResult, "#BBAAAA");selIndex = 0;lastTimeTempResult = "";srcTextRange = taSource.createTextRange();}return;}//\n cannot be found by TextRange.findText, so we try to replace \n with empty first, //if it turns out to be empty, we replace it with \rvar textRangeFinder = rslt[selIndex].replace(/\n/g, "");var methodMask = getShowMethodMask();if (textRangeFinder != "" && srcTextRange.findText(textRangeFinder, 1, 0)){srcTextRange.select();srcTextRange.scrollIntoView();//var offset = srcTextRange.text.length; //actually, textRangeFinder != srcTextRange.text if srcTextRange.text contains \n,//eg. \s+\w+ will match \r\nhellovar offset = textRangeFinder.length;if (offset < 1) //when text is \n or some other special chars, it will happenoffset = 1;srcTextRange.moveStart("character", offset);if ("" != lastTimeTempResult)setResult(lastTimeTempResult, "#BBAAAA");htmlResult(("选中第 " + (selIndex + 1) + " 个匹配:").bold(), ("" != lastTimeTempResult));if (methodMask & 0x02) //method 2: show both visible and invisible chars{htmlResult("<br>" + rslt[selIndex].toVisible(true).fontcolor("gray"), true);}if (methodMask & 0x01) //method 1: only show visible chars{addResult("\n" + rslt[selIndex], "blue");}htmlResult("<br>替换后的结果为:".bold(), true);htmlResult("<button id='btnReplaceSingle' onclick='singleReplace("+ selIndex + ")'>执行单个替换<\/button>", true);var rplcRslt = rslt[selIndex].replace(s, getReplaceValue());if (methodMask & 0x01) //method 1: only show visible chars{addResult("\n" + rplcRslt, "blue");}if (methodMask & 0x02) //method 2: show both visible and invisible chars{htmlResult("<br>" + rplcRslt.toVisible(true).fontcolor("gray"), true);}//show child matchesvar subMatches = null;try{var notGlobelPtn = new RegExp(txtMatchPattern.value, getMode().replace(/g/g, ""));subMatches = rslt[selIndex].match(notGlobelPtn);}catch (e){//do nothing here}if (null == subMatches || subMatches.length <= 1) //no sub matcheshtmlResult("<hr>无子匹配。".bold(), true);else{htmlResult(("<hr>共有 " + (subMatches.length - 1) + " 个子匹配,分别为:").bold(), true);if (methodMask & 0x02) //method 2: show both visible and invisible chars{for (var i = 1; i < subMatches.length; i++){htmlResult(("<br>第 " + i + " 个子匹配 $" + i + ":<br>").bold().fontcolor("gray"), true);htmlResult(subMatches[i].toVisible(true).fontcolor("gray"), true);}}if (methodMask & 0x01) //method 1: only show visible chars{for (var i = 1; i < subMatches.length; i++){htmlResult(("<br>第 " + i + " 个子匹配 $" + i + ":<br>").bold().fontcolor("blue"), true);addResult(subMatches[i], "blue");}}}lastTimeTempResult = "";selIndex++;}else{//if we try to find \s, it will run to here when meets \nsrcTextRange.collapse(true); //do not make it select anythingsrcTextRange.select(); //actually this will move the caret to the right placehtmlResult(("无法将第 " + (selIndex + 1) + " 个匹配[").bold().fontcolor("red"));htmlResult(rslt[selIndex].toVisible(true).fontcolor("blue"), true);htmlResult("]选中。".bold().fontcolor("red"), true);if (methodMask & 0x02) //method 2: show both visible and invisible chars{htmlResult("<br>" + rslt[selIndex].toVisible(true).fontcolor("gray"), true);}if (methodMask & 0x01) //method 1: only show visible chars{addResult("\n" + rslt[selIndex], "blue");}htmlResult("<br>替换后的结果为:".bold(), true);htmlResult("<button id='btnReplaceSingle' onclick='singleReplace("+ selIndex + ")'>执行单个替换<\/button>", true);var rplcRslt = rslt[selIndex].replace(s, getReplaceValue());if (methodMask & 0x01) //method 1: only show visible chars{addResult("\n" + rplcRslt, "blue");}if (methodMask & 0x02) //method 2: show both visible and invisible chars{htmlResult("<br>" + rplcRslt.toVisible(true).fontcolor("gray"), true);}selIndex++;}}else{if ("" == lastTimeTempResult){//restart allselIndex = 0;lastTimeTempResult = "";srcTextRange = taSource.createTextRange();this.onclick();}else{//before restart all, show what we stored before.setResult(lastTimeTempResult, "#BBAAAA");srcTextRange.collapse(true); //do not make it select anythingsrcTextRange.select();lastTimeTempResult = "";}}}function singleReplace(theIndex){    var s = getRegExp();if (null == s){return disableSingleReplace();}var rslt = taSource.value.match(s);if (theIndex < 0 || theIndex >= rslt.length || theIndex != selIndex - 1){return disableSingleReplace(); //invalid param theIndex}var textRangeFinder = rslt[theIndex].replace(/\n/g, "");var rplcRslt = rslt[theIndex].replace(s, getReplaceValue());srcTemp = taSource.value;srcTextRange.moveStart("character", -textRangeFinder.length);srcTextRange.text = rplcRslt; //replace//select againsrcTextRange.moveStart("character", -rplcRslt.length);srcTextRange.select();srcTextRange.scrollIntoView();//important: rehighlight the matcheshighLightSource();var btn = document.getElementById("btnReplaceSingle");if (null != btn){btn.innerText = "撤消单个替换";btn.id = "btnUndoSingleReplace";btn.onclick = undoReplaceAction;}}function undoReplaceAction(strResult){var strShow = "已撤销替换动作。";if (strResult && strResult.length > 0)strShow = strResult;setSourceValue(srcTemp);srcTemp = "";setResult(strShow, "#006600"); //this will help us delete the button}function disableSingleReplace(){var btn = document.getElementById("btnReplaceSingle");if (null != btn){btn.disabled = true;}}function invalidateSelection(){selIndex = -1;var btn = document.getElementById("btnReplaceSingle");if (null != btn){btn.disabled = true;}}function initResult(){document.title += "[" + document.lastModified + "]";htmlResult("预览区域,特殊字符说明如下:<br>");htmlResult(" :English Space,英文空格,即半角空格;<br>".toVisible(), true);htmlResult(" :Chinese Space,中文空格,即全角空格;<br>".toVisible(), true);htmlResult("\t:制表符Tab,即ASCII码为0x09的字符;<br>".toVisible(), true);htmlResult("\n:换行符,即ASCII码为0x0A的字符;<br>".toVisible(), true);htmlResult("\r:回车符,即ASCII码为0x0D的字符;<br>".toVisible(), true);htmlResult("\f:走页换纸符,即ASCII码为0x0C的字符,一般很少碰到;<br>".toVisible(), true);htmlResult("\b:退格符,即ASCII码为0x08的字符(注意不是正则里的\\b),一般很少碰到;<br>".toVisible(), true);htmlResult("<font color='black'><b>,</b></font>:<b>黑色粗体的中文全角逗号</b>"+ "用来分隔匹配(在计算匹配次数时)。<br>", true);addResult("另外:预览方法的方法一(蓝色显示可见字符)比较直观,"+ "而方法二(灰色显示所有字符)可以让你看清所有字符尤其是不可见字符的替换情况。");makeTextAreaTabKey(); //允许textarea输入tabinitComRegExpSelectOptions();//highLightSource();}window.onload = initResult;//from 我是程序员(http://www.wscxy.com) , By Shosh whose qq is 124727276--></script></HTML>

原创粉丝点击