//模式匹配 import fonts.fontAwesome; import win.ui; import win.ui.menu; /*DSG{{*/ var winform = win.form(text="模式匹配辅助工具";right=840;bottom=584;bgcolor=16579578) winform.add( btnSave={cls="button";text="保存代码";left=598;top=88;right=662;bottom=112;disabled=1;dl=1;dt=1;tabstop=1;z=11}; button={cls="button";text="转义符 \";left=539;top=25;right=611;bottom=49;dl=1;dt=1;tabstop=1;z=7}; button11={cls="button";text="字符集 []";left=276;top=25;right=348;bottom=49;dl=1;dt=1;tabstop=1;z=22}; button12={cls="button";text="补 集 [^]";left=363;top=25;right=435;bottom=49;dl=1;dt=1;tabstop=1;z=19}; button13={cls="button";text="字符类...";left=188;top=25;right=260;bottom=49;dl=1;dt=1;tabstop=1;z=10}; button14={cls="button";text="数字...";left=17;top=55;right=78;bottom=79;dl=1;dt=1;tabstop=1;z=21}; button15={cls="button";text="字符串...";left=91;top=55;right=154;bottom=79;dl=1;dt=1;tabstop=1;z=6}; button16={cls="button";text="模式运算符...";left=627;top=25;right=743;bottom=49;dl=1;dt=1;tabstop=1;z=4}; button17={cls="button";text="网 址";left=166;top=55;right=214;bottom=79;dl=1;dt=1;tabstop=1;z=18}; button18={cls="button";text="I D";left=227;top=55;right=275;bottom=79;dl=1;dt=1;tabstop=1;z=8}; button19={cls="button";text="更多...";left=288;top=55;right=336;bottom=79;dl=1;dt=1;tabstop=1;z=12}; button2={cls="button";text="测试模式";left=436;top=87;right=516;bottom=111;dl=1;dt=1;tabstop=1;z=15}; button3={cls="button";text="复制代码";left=522;top=88;right=590;bottom=112;disabled=1;dl=1;dt=1;tabstop=1;z=13}; button6={cls="button";text="元序列 <>";left=451;top=25;right=523;bottom=49;dl=1;dt=1;tabstop=1;z=14}; button8={cls="button";text='串结束\uFF04';left=100;top=25;right=172;bottom=49;dl=1;dt=1;tabstop=1;z=5}; button9={cls="button";text="串开始 ^";left=17;top=25;right=84;bottom=49;dl=1;dt=1;tabstop=1;z=23}; chkFind={cls="radiobutton";text="查 找";left=352;top=59;right=416;bottom=81;bgcolor=16579578;checked=1;dl=1;dt=1;tabstop=1;z=27}; chkMatch={cls="radiobutton";text="匹 配";left=416;top=59;right=464;bottom=81;bgcolor=16579578;dl=1;dt=1;tabstop=1;z=28}; chkMatchGlobal={cls="checkbox";text="全局匹配";left=550;top=58;right=626;bottom=80;checked=1;dl=1;dt=1;hide=1;tabstop=1;z=30}; chkReplace={cls="radiobutton";text="替 换";left=488;top=59;right=544;bottom=81;bgcolor=16579578;dl=1;dt=1;tabstop=1;z=29}; groupbox={cls="groupbox";text="匹配模式:";left=9;top=6;right=829;bottom=120;aw=1;bgcolor=16777215;dl=1;dr=1;dt=1;edge=1;tabstop=1;z=1}; groupbox2={cls="groupbox";text="匹配结果:";left=579;top=123;right=830;bottom=578;bgcolor=16777215;db=1;dr=1;dt=1;edge=1;tabstop=1;z=2}; groupbox3={cls="groupbox";text="测试文本:";left=9;top=123;right=575;bottom=579;ah=1;aw=1;bgcolor=16777215;db=1;dl=1;dr=1;dt=1;edge=1;tabstop=1;z=3}; lbReplace={cls="static";text="替换次数:";left=663;top=59;right=719;bottom=81;center=1;dl=1;dt=1;hide=1;tabstop=1;transparent=1;z=32}; lnkDocument={cls="plus";text=" 模式语法文档";left=679;top=85;right=811;bottom=116;align="left";color=8388608;dl=1;dt=1;font=LOGFONT(h=-14);iconStyle={align="left";font=LOGFONT(name='FontAwesome');padding={left=10}};iconText='\uF059';notify=1;textPadding={left=21};z=34}; lstMatch={cls="listbox";left=585;top=141;right=823;bottom=575;bgcolor=16777215;db=1;dr=1;dt=1;edge=1;hscroll=1;items={"这里显示模式匹配结果:"};tabstop=1;vscroll=1;z=24}; static={cls="static";text="文件路径:";left=47;top=143;right=114;bottom=159;dl=1;dt=1;tabstop=1;transparent=1;z=20}; txtBrowser={cls="button";text="浏览...";left=449;top=137;right=505;bottom=161;dl=1;dt=1;tabstop=1;z=16}; txtPath={cls="edit";text="选择浏览读取要匹配的文本...";left=120;top=137;right=440;bottom=161;dl=1;dt=1;edge=1;multiline=1;tabstop=1;z=9}; txtPattern={cls="edit";left=57;top=88;right=425;bottom=112;dl=1;dt=1;edge=1;tabstop=1;z=25}; txtRep={cls="edit";text="请输入替换内容";left=552;top=59;right=656;bottom=81;dl=1;dt=1;edge=1;hide=1;multiline=1;tabstop=1;z=31}; txtRepCount={cls="edit";text="默认替换全部";left=725;top=59;right=817;bottom=81;dl=1;dt=1;edge=1;hide=1;multiline=1;tabstop=1;z=33}; txtResult={cls="edit";text="显示模式替换结果...";left=585;top=140;right=815;bottom=569;db=1;dr=1;dt=1;edge=1;hide=1;hscroll=1;multiline=1;tabstop=1;vscroll=1;z=17}; txtSource={cls="edit";left=18;top=172;right=566;bottom=572;ah=1;aw=1;db=1;dl=1;dr=1;dt=1;edge=1;hscroll=1;multiline=1;vscroll=1;z=26} ) /*}}*/ import win.ui.atom; var atom,hwnd = winform.atom("aardio.pattern.F4700CFB-B4ED-4637-8F19-C76B3B8DC7F9"); if(!atom){ win.quitMessage(); return; } winform.enableDpiScaling(); winform.txtSource.limit = 0x10400; winform.lstMatch.oncommand = function( id,event ){ if( event = 0x1/*_LBN_SELCHANGE*/ ){ var index = winform.lstMatch.selIndex; var strSource = winform.txtSource.text; var pos, pos2 = 1, 1; if( winform.chkMatch.checked){ for(i=1;index;1){ pos, pos2 = string.find(strSource,winform.txtPattern.text,pos2+1 ); if( !pos )return; } } if( !pos or (pos2 != 1) ){ pos, pos2 = string.find(strSource,winform.txtPattern.text,pos - 1,true ); winform.txtSource.setSel( pos, pos2); var line = winform.txtSource.lineFromChar( pos ); winform.txtSource.scrollCaret(); } } } winform.button15.oncommand = function(hwnd,event){ winform.txtPattern.text = ""; var popmenu = win.ui.popmenu(winform); popmenu.add('对称双引号',insertExpressionMenu( '%""')); popmenu.add('对称单引号',insertExpressionMenu( "%''")); popmenu.add('英文字母串',insertExpressionMenu( "^[A-Za-z]+$")); popmenu.add('大写英文串',insertExpressionMenu( "^[A-Z]+$")); popmenu.add('小写英文串',insertExpressionMenu( "^[a-z]+$")); popmenu.add('数字和字母串',insertExpressionMenu( "^[A-Za-z0-9]+$")); popmenu.add('数字、字母或下划线串',insertExpressionMenu( "^\w+$") ); popmenu.add('邮箱地址',insertExpressionMenu( "\w+[\w\-\.]+\w@\w+[\w\-]*\w\.[\w\-\.]*\w{2,}") ); popmenu.popup(winform.button15.left,winform.button15.bottom); } winform.button14.oncommand = function(hwnd,event){ winform.txtPattern.text = ""; var popmenu = win.ui.popmenu(winform); popmenu.add('匹配正整数',insertExpressionMenu( "^[1-9]\d*$")); popmenu.add('匹配负整数',insertExpressionMenu( "^\-[1-9]\d*$")); popmenu.add('匹配整数',insertExpressionMenu( "^\-?[1-9]\d*$")); popmenu.add('匹配非负整数',insertExpressionMenu( "^[1-9]\d*$")); popmenu.add('匹配非正整数',insertExpressionMenu( "^\-[1-9]\d*$")); popmenu.add('匹配正浮点数',insertExpressionMenu( "^\d*\.\d*") ); popmenu.add('匹配负浮点数',insertExpressionMenu( "^\-^\d*\.\d*$") ); popmenu.add('匹配浮点数',insertExpressionMenu( "^\-?^\d*\.\d*$") ); popmenu.popup(winform.button14.left ,winform.button14.bottom); } winform.button19.oncommand = function(hwnd,event){ winform.txtPattern.text = ""; var popmenu = win.ui.popmenu(winform); popmenu.add('PASCAL语句块',insertExpressionMenu( "%<\Wbegin\W><\Wend\W>?")); popmenu.add('IP',insertExpressionMenu( "\d+\.\d+\.\d+\.\d+")); popmenu.add('QQ号',insertExpressionMenu( "[1-9][0-9]{4,15}")); popmenu.add('中文',insertExpressionMenu( "(<\xA1-\xF7\xA1-\xFE>+)")); popmenu.add('空行',insertExpressionMenu( "\n\s*[\r\n]")); popmenu.add('邮编',insertExpressionMenu( "[1-9]\d{5}![\d]")); popmenu.add('HTML',insertExpressionMenu( "(\<(\S*?)[^>]*\>(.*?)\)")); popmenu.add('超链接',insertExpressionMenu( "(\s+href\s*=\s*([""'])[^""']+\2)" ) ); popmenu.add('身份证号',insertExpressionMenu( "\d{15,18}") ); popmenu.popup(winform.button19.right - 45 ,winform.button19.bottom); } winform.button18.oncommand = function(hwnd,event){ winform.txtPattern.text = ""; insertExpression( "^[a-zA-Z][a-zA-Z0-9_]{4,15}$" ); } winform.button17.oncommand = function(hwnd,event){ winform.txtPattern.text = ""; insertExpression( "\a+\://\S*" ); } winform.button12.oncommand = function(hwnd,event){ insertExpression( "[^]" ); } winform.button11.oncommand = function(hwnd,event){ insertExpression( "[]" ); } winform.button9.oncommand = function(hwnd,event){ insertExpression( "^" ); } winform.button8.oncommand = function(hwnd,event){ insertExpression( "$" ); } winform.button6.oncommand = function(hwnd,event){ insertExpression( "<>" ); } insertExpression = function( strInsert, cursorPos = 0 ){ winform.txtPattern.color = 0; winform.txtPattern.redraw(); var strExpression = winform.txtPattern.text; var strLastchar = string.right(strExpression,1); var strfirstchar = string.left( strInsert,1); if( strfirstchar=="<" or strfirstchar=="[" or strfirstchar=="!") strExpression += strInsert; else if( strLastchar == ']') { strExpression = string.trimright( strExpression ,']'); strExpression += (strInsert +']'); } else if( strLastchar == '>' ){ strExpression = string.left( strExpression,#strExpression-1) strExpression += (strInsert +'>'); } else strExpression += strInsert; winform.txtPattern.text = strExpression; } insertExpressionMenu = function( strInsert, cursorPos = 0 ){ return function(){ insertExpression( strInsert, cursorPos ); } } winform.button.oncommand = function(hwnd,event){ insertExpression( "\"); } winform.button16.oncommand = function(hwnd,event){ var popmenu = win.ui.popmenu(winform); popmenu.add('P? 匹配子模式 P 零或一次',insertExpressionMenu( "?")); popmenu.add() popmenu.add('P+ 长匹配子模式 P 一次或多次',insertExpressionMenu( "+")); popmenu.add('P+? 短匹配子模式 P 一次或多次',insertExpressionMenu( "+?")); popmenu.add() popmenu.add('P* 长匹配子模式 P 零次以上',insertExpressionMenu( "*")); popmenu.add('P*? 短匹配子模式 P 零次以上',insertExpressionMenu( "*?")); popmenu.add() popmenu.add('P{n,m} 匹配子模式 P 最少 n 最多 m 次',insertExpressionMenu( "{n,m}") ); popmenu.add() popmenu.add('P1|P2 匹配子模式 P 或 P2 其中之一',insertExpressionMenu( "|")); popmenu.add('P1&P2 同时匹配子模式 P 或 P2',insertExpressionMenu( "&")); popmenu.add() popmenu.add('%Pp 子模式 P 到 p 对称匹配',function() winform.txtPattern.appendText( "%()")); popmenu.add() popmenu.add('P?= 零宽预测断言',function() winform.txtPattern.appendText( "?=")); popmenu.add('P?! 零宽预测断言(逻辑取反)',function() winform.txtPattern.appendText( "?!")); popmenu.add('!p 零宽边界断言',function() winform.txtPattern.appendText( "!\wword!\W")); popmenu.add() popmenu.add() popmenu.popup(winform.button16.right - 80 ,winform.button16.bottom); } winform.button13.oncommand = function(hwnd,event){ var popmenu1 = win.ui.popmenu(winform); popmenu1.add('. 任意字节',insertExpressionMenu( ".") ); popmenu1.add(': 任意汉字',insertExpressionMenu( ":") ); popmenu1.add('\\a 字母',insertExpressionMenu( "\a")); popmenu1.add('\\c 控制字符',insertExpressionMenu( "\c")); popmenu1.add('\\d 数字',insertExpressionMenu( "\d")); popmenu1.add('\\i 是否ASCII字符',insertExpressionMenu( "\i")); popmenu1.add('\\l 小写字母',insertExpressionMenu( "\l")); popmenu1.add('\\p 标点字符',insertExpressionMenu( "\p")); popmenu1.add('\\s 空白符',insertExpressionMenu( "\s")); popmenu1.add('\\u 大写字母',insertExpressionMenu( "\u")); popmenu1.add('\\w 字母和数字',insertExpressionMenu( "\w")); popmenu1.add('\\x 十六进制数字',insertExpressionMenu( "\x")); popmenu1.add('\\n 换行符',insertExpressionMenu( "\n")); popmenu1.add('\\r 回车符',insertExpressionMenu( "\r")); popmenu1.add('\\f 换页符',insertExpressionMenu( "\f")); popmenu1.add('\\v 匹配一个垂直制表符 ',insertExpressionMenu( "\v")); popmenu1.add('\\z\\0 字节码为0的字符',insertExpressionMenu( "\z")); popmenu1.add('注:大写表示小写集合的补集',function(){}); popmenu1.popup(winform.button13.right - 70 ,winform.button13.bottom); } import fsys.dlg; winform.btnSave.oncommand = function(hwnd,event){ var strPath = winform.txtPath.text; var strBuffer; if( not winform.txtResult.hide ){ strBuffer = winform.txtResult.text; } else{ var tab = winform.lstMatch.items; } if( strPath != ""){ var filename = fsys.dlg.save( "文本文件|*.txt|所有文件|*.*||" ,"保存模式测试结果", strPath); if(filename){ string.save(filename, strBuffer ); } } } winform.chkFind.oncommand = function(hwnd,event){ winform.chkMatchGlobal.hide = true; winform.txtRep.hide = true; winform.txtRepCount.hide = true; winform.lbReplace.hide = true; winform.txtResult.hide = true; winform.lstMatch.hide = false;; } winform.chkReplace.oncommand = function(hwnd,event){ winform.chkMatchGlobal.hide = true; winform.txtRep.hide = false;; winform.txtRepCount.hide = false;; winform.lbReplace.hide = false;; winform.txtResult.hide = false;; winform.lstMatch.hide = true; } winform.chkMatch.oncommand = function(hwnd,event){ winform.chkMatchGlobal.hide = false;; winform.txtRep.hide = true; winform.txtRepCount.hide = true; winform.lbReplace.hide = true; winform.txtResult.hide = true; winform.lstMatch.hide = false;; } import win.clip; winform.button3.oncommand = function(hwnd,event){ if(!#winform.aardioCode){ return winform.txtPattern.showWarningTip("请输入模式串,然后点击测试运行以生成示例代码。"); } win.clip.write( winform.aardioCode ); } winform.txtResult.oncommand = function(hwnd,event){ if( winform.txtResult.text == "显示模式匹配结果..."){ winform.txtResult.text = ""; winform.txtResult.color = 0; winform.txtResult.redraw(); } } winform.txtRepCount.oncommand = function(hwnd,event){ if( winform.txtRepCount.text == "默认替换全部"){ winform.txtRepCount.text = ""; winform.txtRepCount.color = 0; winform.txtRepCount.redraw(); } } winform.txtRep.oncommand = function(hwnd,event){ if( winform.txtRep.text == "请输入替换内容"){ winform.txtRep.text = ""; winform.txtRep.color = 0; winform.txtRep.redraw(); } } winform.txtPath.oncommand = function(hwnd,event){ if( winform.txtPath.text == "选择浏览读取要匹配的文本..."){ winform.txtPath.text = ""; winform.txtPath.color = 0; winform.txtPath.redraw(); } } winform.txtSource.oncommand = function(hwnd,event){ if( winform.txtSource.text == "请输入测试文本..."){ winform.txtSource.text = ""; winform.txtSource.color = 0; winform.txtSource.redraw(); } } winform.txtBrowser.oncommand = function(hwnd,event){ var strTemp = winform.txtPath.text; var strfile = fsys.dlg.open( "文本文件|*.txt|所有文件|*.*||", "选择要匹配的文本文件" ); if(strfile){ assert( string.load( strfile ) ); winform.txtSource.text = string.load( strfile ); winform.txtPath.text = strfile; winform.txtPath.color = 0; winform.txtPath.redraw(); winform.txtSource.color = 0; winform.txtSource.redraw(); } } patternReplace = function( str,pattern ,patternTemplate,replaceText,replacecount ){ var strReplaceCode; var aardioCode = /*** var str = /************* %s *************/ var pattern = %s var replaceText = "%s"; ***/ if( replacecount == "默认替换全部" ){ strtemp = string.replace( str, pattern, replaceText ); strReplaceCode = "strReplaceResult = string.replace( str, pattern, replaceText);" aardioCode = string.format(aardioCode+strReplaceCode , str, patternTemplate ,replaceText ); } else if( tonumber( replacecount ) ){ strtemp = string.replace( str,pattern,replaceText,replacecount); strReplaceCode = /*****var replacecount = "%s"; strReplaceResult = string.replace( str,pattern,replaceText,replacecount); *****/ aardioCode = string.format( aardioCode+strReplaceCode , str,patternTemplate ,replaceText, replacecount ) } else{ strtemp = "错误,请输入替换次数,必须为正整数!" aardioCode = "错误,请输入替换次数,必须为正整数!" return strtemp, aardioCode ; } return strtemp, aardioCode; } gMatch = function(str,regex){ var items = {} string.replace(str,regex,function( ... ){ var matchs = {...}; table.push( items, table.tostring(matchs) ); } ); if( #items ==0 ){ winform.lstMatch.items = {"匹配结果为空..."}; return ; } winform.lstMatch.items = items; return items; } patternMatch = function( str, pattern,patternTemplate ){ var strMatchCode; var aardioCode = /*** var str = /************* %s *************/ var pattern = %s ***/ winform.lstMatch.clear(); if( winform.chkMatchGlobal.checked == true ){ gMatch(str, pattern ); strtemp = string.gmatch( str, pattern ); strMatchCode = /***** for s in string.gmatch( str, pattern ){ } *****/ } else{ strtemp = string.match( str, pattern ); var items = {} table.push( items, strtemp); winform.lstMatch.items = items; strMatchCode = "strMatchResult = string.match( str, pattern );" } aardioCode = string.format(aardioCode+strMatchCode , str, patternTemplate ); return aardioCode; } patternFind = function( str, pattern ,patternTemplate){ var aardioCode = /*** var str = /************* %s *************/ var pattern = %s i,j = string.find( str, pattern ); ***/ i,j = string.find( str, pattern ); //使用模式匹配查找字符串并返回起始位置(i),结束位置(j); if( i ){ strtemp1 = string.format('串起始位置i="%d":', i); strtemp2 = string.format('串结束位置j="%d":', j); i,j = string.find( str, pattern,,true ); winform.txtSource.setSel( i, j ); } else{ strtemp1 = "没有找到相匹配的文本!"; strtemp2 = strtemp1; } winform.lstMatch.clear(); var items = {} table.push( items, strtemp2); table.push( items, strtemp1); winform.lstMatch.items = items; aardioCode = string.format( aardioCode, str, patternTemplate ); return aardioCode; } winform.button2.oncommand = function(hwnd,event) { var strtemp,aardioCode = "请输入测试模式串", "匹配文本和模式串为空,生成 aardio 示例代码失败!"; var pattern,str = winform.txtPattern.text,winform.txtSource.text; var patternType = ( winform.chkFind.checked ? winform.chkFind.id) or ( winform.chkMatch.checked ? winform.chkMatch.id) or ( winform.chkReplace.checked ? winform.chkReplace.id ); var replaceText, replacecount = winform.txtRep.text, winform.txtRepCount.text ; var patternTemplate = '"' + pattern + '"'; if( ..string.find(pattern,'["\']') ){ patternTemplate = "//" + pattern ; } select(patternType) { case winform.chkFind.id { if( str != "" and pattern != "" ){ aardioCode = patternFind( str, pattern ,patternTemplate) } else{ aardioCode = "请输入要查找的目标文本和模式串"; } } case winform.chkMatch.id { aardioCode = patternMatch( str, pattern ,patternTemplate); } case winform.chkReplace.id { if( str != "" and pattern != "" ){ strtemp, aardioCode = patternReplace( str, pattern,patternTemplate, replaceText, replacecount ); winform.txtResult.text = strtemp; } else{ aardioCode = "错误,请输入要查找的目标文本和模式串"; winform.txtResult.text = "错误,请输入需要替换的目标文本!" } } } winform.lstMatch.color = 0; winform.lstMatch.redraw(); winform.txtResult.redraw(); //显示自动生成的代码 winform.aardioCode = aardioCode; winform.txtPattern.showInfoTip(winform.aardioCode); //启用复制代码和保存结果按钮 winform.button3.disabled = false; winform.btnSave.disabled = false; } winform.txtPattern.setCueBannerText("请输入测试模式串 ..."); winform.lnkDocument.skin({ color={ active=0xFF00FF00; default=0xFF000080; disabled=0xFF6D6D6D; hover=0xFFFF0000 } }) winform.lnkDocument.oncommand = function(id,event){ import ide; ide.openDocument("doc://library-guide/builtin/string/patterns.html") } winform.show(true) win.loopMessage( winform );