Board logo

标题: 正则复制工具repy.exe [打印本页]

作者: happy886rr    时间: 2017-2-24 23:01     标题: 正则复制工具repy.exe

REPY.EXE [VERSION 1.1]
链接: https://pan.baidu.com/s/1uWpc2Hgu5-C9sKM1FFoCNw?pwd=sfaa

摘要:
=============================================================================
兼容PERL正则语法的文件复制工具。支持指定目录,子目录搜寻,对匹配到的文件亦可
进行正则更名复制。同时支持高亮彩显。

支持 IGNORECASE, SINGLELINE, MULTILINE 等常见匹配模式。支持命名分组, 条件表
达式,递归表达式等多种高级特性。本工具引用了DEELX正则库版权归DEELX作者所有,
其余代码版权归本人所有。

DEELX正则库deelx.h下载地址 http://www.regexlab.com/deelx/
=============================================================================

语法:
  1. DEELX 正则表达式中标准的字符集合有:
  2. 字符集合
  3. 说明
  4. .
  5. 小数点可以匹配除了换行符(\n)以外的任意一个字符
  6. \w
  7. 可以匹配任何一个字母或者数字或者下划线
  8. \W
  9. W大写,可以匹配任何一个字母或者数字或者下划线以外的字符
  10. \s
  11. 可以匹配空格、制表符、换页符等空白字符的其中任意一个
  12. \S
  13. S大写,可以匹配任何一个空白字符以外的字符
  14. \d
  15. 可以匹配任何一个 0~9 数字字符
  16. \D
  17. D大写,可以匹配任何一个非数字字符
  18. [:alpha:]
  19. POSIX 格式,可以匹配任何一个字母
  20. [:^alpha:]
  21. POSIX 否定格式,可以匹配任何一个字母以外的字符
  22. 如果正则表达式匹配模式为 SINGLELINE,小数点可以匹配包含换行符在内的任一字符。更多详情,参见正则表达式匹配模式。
  23. DEELX 支持的 POSIX 字符集合定义有:
  24. POSIX 字符集合
  25. 说明
  26. [:alnum:]
  27. 任何一个字母或数字(A - Z, a - z, 0 - 9)
  28. [:alpha:]
  29. 任何一个字母(A - Z, a - z)
  30. [:ascii:]
  31. 任何一个 ASCII 范围内字符(\x00 – \x7F)
  32. [:cntrl:]
  33. 任何一个控制字符(\x00 – \x1F, \x7F)
  34. [:digit:]
  35. 任何一个数字(0 – 9)
  36. [:print:]
  37. 任何一个可显示的 ASCII 字符(\x20 – \x7E)
  38. [:space:]
  39. 任何一个空白字符(\x09 – \x0D, \x20)
  40. [:graph:]
  41. 任何一个可显示的 ASCII 字符,不包含空格(\x21 – \x7E)
  42. [:lower:]
  43. 任何一个小写字母(a – z)
  44. [:punct:]
  45. 可显示字符 [:print:] 中除去字母数字 [:alnum:]
  46. [:upper:]
  47. 任何一个大写字母(A – Z)
  48. [:xdigit:]
  49. 任何一个十六进制数字(0 - 9, A - F, a - f)
  50. [:blank:]
  51. 空格或者制表符(\x20, \x09)
复制代码
用法:
-----------------------------------------------------------------------------
repy [match expression] [format expression]
-----------------------------------------------------------------------------
     /r  Recursive subdirectories         REM 递归子目录
     /f  Force copy                       REM 强制复制文件
-----------------------------------------------------------------------------

示例:
-----------------------------------------------------------------------------
REM 递归子目录复制到H盘test目录下
repy /r (.*\.tlog) h:\test\$1

REM 将制定目录文件复制到制定目录,请转义斜杠
repy /f   E:\\li\\desk\\新建文件夹\\src\\Release\\1.txt   H:\1.txt

-----------------------------------------------------------------------------

英译:
-----------------------------------------------------------------------------
REGULAR COPY TOOLS, COPYRIGHT@2017~2019 BY HAPPY
-----------------------------------------------------------------------------
repy [match expression] [format expression]
-----------------------------------------------------------------------------
     /help  Show help information
     /r     Recursive subdirectories               
     /f     Force copy
-----------------------------------------------------------------------------
2017-02-25
  1. /*
  2. REGULAR COPY TOOLS, COPYRIGHT@2016~2018 BY HAPPY, VERSION 1.1
  3. REPY.EXE
  4. */
  5. #include   "deelx.h"
  6. #include <windows.h>
  7. #include  <direct.h>
  8. #include   <stdio.h>
  9. #include  <assert.h>
  10. #include  <stdlib.h>
  11. #include  <string.h>
  12. #include      <io.h>
  13. /***************定义全局变量*************/
  14. //百分比标记
  15. char perMARKS[51];
  16. //进度条容器
  17. const char proGRESS[128]="[                                                      ]\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b";
  18. //定义路径名最大长度(字节)
  19. #define  PATH_SIZE   512
  20. //定义文件名最大长度(字节)
  21. #define  FNAME_SIZE 1024
  22. //主窗口句柄
  23. HANDLE handle_out;
  24. //定义帮助说明
  25. #define HELP_INFORMATION "\
  26. -----------------------------------------------------------------\n\
  27. REGULAR COPY TOOLS, COPYRIGHT@2017~2019 BY HAPPY, VERSION 1.1\n\
  28. -----------------------------------------------------------------\n\
  29. repy [match expression] [format expression]\n\
  30. -----------------------------------------------------------------\n\
  31.      /h  Show help information\n\
  32.      /r  Recursive subdirectories\n\
  33.      /f  Force copy\n\
  34. -----------------------------------------------------------------\n\
  35. 2017-02-25"
  36. /***************功能函数群***************/
  37. char* strrstr(const char *dst, const char *src)  
  38. {  
  39. assert(dst);assert(src);  
  40. const char *pdst=dst, *psrc=src;
  41. char *ret=NULL;  
  42. while(*dst){
  43. while(*pdst==*psrc){
  44. if(*pdst=='\0'){
  45. return ret=(char*)dst;
  46. }else{  
  47. pdst++;  
  48. psrc++;  
  49. }  
  50. }  
  51. if(*psrc=='\0'){ret=(char*)dst;}
  52. pdst=++dst;  
  53. psrc=src;  
  54. }  
  55. return ret;  
  56. }
  57. //进度条回调函数
  58. DWORD CALLBACK CopyProgressRunTim(
  59. LARGE_INTEGER tFileSize,
  60. LARGE_INTEGER tTransferred,
  61. LARGE_INTEGER StreamSize,
  62. LARGE_INTEGER Streamferred,
  63. DWORD  StreamNumber,
  64. DWORD  CallbackReason,
  65. HANDLE SourceFile,
  66. HANDLE DestinationFile,
  67. LPVOID lpData
  68. )
  69. {
  70. //计算进度
  71. int i=(tFileSize.LowPart<=0) ?100 :(tTransferred.LowPart*1.0)/(tFileSize.LowPart)*100, j=i>>1;
  72. //显示递增进度
  73. while((j--)>perMARKS[0] && !(perMARKS[j])){perMARKS[j]=TRUE; fputc('=', stdout);}
  74. perMARKS[0]=i>>1;
  75. //显示进度百分比
  76. fprintf(stdout, "%02d%%\b\b\b", i);
  77. //回调
  78. return PROGRESS_CONTINUE;
  79. }
  80. //正则命名函数
  81. void ReCopy(
  82. int FLAG,             //复制模式开关
  83. const char* Org_Path, //工作目录
  84. char* RE_Match,       //要匹配的正则
  85. char* RE_Format       //要更名的正则
  86. )
  87. {
  88. //设置工作目录
  89. _chdir(Org_Path);
  90. struct _finddata_t FileS;
  91. intptr_t handle=_findfirst("*",&FileS);
  92. bool M=(handle==-1)?TRUE:FALSE;
  93. while(!M){
  94. if(
  95. (strcmp(FileS.name, ".")==0) ||
  96. (strcmp(FileS.name,"..")==0)
  97. ){
  98. M=(_findnext(handle, &FileS)!=0)?TRUE:FALSE;
  99. continue;
  100. }
  101. //匹配正则
  102. CRegexpT<char> regexp(RE_Match);
  103. MatchResult result=regexp.Match(FileS.name);
  104. //执行复制
  105. if(result.IsMatched()){
  106.     //正则替换
  107. char* tpSTR=regexp.Replace(FileS.name, RE_Format);
  108. //绘进度条
  109. SetConsoleTextAttribute(handle_out, 1|4|8);  //紫色
  110. fprintf(stdout, "Copy... ");
  111. SetConsoleTextAttribute(handle_out, 2|8);    //绿色
  112. fprintf(stdout, "%s -> %s\n", FileS.name, tpSTR);
  113. SetConsoleTextAttribute(handle_out, 2|4|8);  //黄色
  114. fputs(proGRESS, stdout);
  115. //初始化进度数组
  116. memset(perMARKS, FALSE, 50);
  117. //强制删除
  118. if(FLAG==0x01){remove(tpSTR);}
  119. //复制文件
  120. if(!CopyFileEx(FileS.name, tpSTR, (LPPROGRESS_ROUTINE)CopyProgressRunTim, NULL, FALSE, COPY_FILE_FAIL_IF_EXISTS)){
  121. SetConsoleTextAttribute(handle_out, 4|8);
  122. fprintf(stdout, "Failed to copy, Check if the target path exists");
  123. }
  124. SetConsoleTextAttribute(handle_out, 1|2|4|8);//白色
  125. fputs("\n\n", stdout);
  126. //释放字串
  127. CRegexpT<char>::ReleaseString(tpSTR);
  128. }
  129. M=(_findnext(handle, &FileS)!=0)?TRUE:FALSE;
  130. }
  131. _findclose(handle);
  132. //递归子目
  133. if(FLAG==0x02){
  134. handle=_findfirst("*.*", &FileS);
  135. M=(handle==-1)?true:false;
  136. while(!M){
  137. if(FileS.attrib & _A_SUBDIR){
  138. if(
  139. (strcmp(FileS.name, ".")!=0) &&
  140. (strcmp(FileS.name,"..")!=0)
  141. ){
  142. //正则复制
  143. ReCopy(FLAG, FileS.name, RE_Match, RE_Format);
  144. }
  145. }
  146. M=(_findnext(handle, &FileS)!=0);
  147. }
  148. _findclose(handle);
  149. }
  150. //还原目录、释放内存
  151. _chdir(Org_Path);
  152. }
  153. /*************MAIN主函数入口*************/
  154. int main(int argc, char ** argv)
  155. {
  156. //检查输入参数是否存在错误
  157. if(
  158. (argc!=3 && argc!=4        )   ||
  159. (argc==3 && argv[1][0]=='/')   ||
  160. (argc==4 && argv[1][0]!='/')   ||
  161. (
  162. argc>1          &&
  163. argv[1][0]=='/' &&
  164. (
  165. argv[1][1]=='?'||
  166. argv[1][1]=='h'||
  167. argv[1][1]=='H'
  168. )
  169. )
  170. ){
  171. fputs(HELP_INFORMATION, stdout);
  172. exit(0);
  173. }
  174. //模式变量
  175. int i=1, FLAG=0x00;
  176. //解析开关
  177. if(argv[i][0]=='/' && argc==4){
  178. switch(argv[i][1])
  179. {
  180. case 'f':
  181. case 'F':
  182. FLAG=0x01, i++;
  183. break;
  184. case 'r':
  185. case 'R':
  186. FLAG=0x02, i++;
  187. break;
  188. default:
  189. //无法识别的开关
  190. fprintf(stderr, "Unrecognized switch '%s'\n", argv[i]);
  191. exit(1);
  192. }
  193. }
  194. handle_out=GetStdHandle(STD_OUTPUT_HANDLE);
  195. char* Org_Path=(char*)calloc(PATH_SIZE, sizeof(char));
  196. char* p=strrstr(argv[i], "\\\\");
  197. if(p!=NULL){
  198. strncpy_s(Org_Path, PATH_SIZE, (const char*)argv[i], (int)p-(int)argv[i]);
  199. ReCopy(FLAG,  Org_Path, p+2, argv[i+1]);
  200. }else{
  201. ReCopy(FLAG,   ".", argv[i], argv[i+1]);
  202. }
  203. return 0;
  204. }
复制代码
该工具是带有精细进度条 且 兼容perl类正则语法 的文件复制工具。

Copy..  (test).txt    $1\.ini     
[>>>>>>>>>>>>>>>>>75%                              ]
[/code]这也是本人最后一个开源第三方,之后的作品将不再提供任何源码,转为提供更详细的使用说明。
作者: codegay    时间: 2017-2-24 23:51

开源啊,虽然我看不懂~~
作者: happy886rr    时间: 2017-2-25 07:15

回复 2# codegay
好的,以后放github了,那样好管理。
作者: freesoft00    时间: 2017-2-25 15:47

回复 1# happy886rr


    也来个注册表的批量替换删除吧,支持正则。
作者: happy886rr    时间: 2017-2-25 19:05

本帖最后由 happy886rr 于 2017-2-25 19:12 编辑

回复 4# freesoft00
已升级到1.1彩色版,请及时下载最新版使用,更新修复了旧版的7个错误,代码共计更新50处。注册表涉及到系统敏感部位,第三方不建议随意修改注册表,那样会大乱的,建议注册表还是用带UI界面的慢慢查找,仔细修改,否则交给第三方,批量替换错误了,会开不了机的。
作者: happy886rr    时间: 2017-2-25 19:06

本帖最后由 happy886rr 于 2017-2-25 19:13 编辑

回复 0# yu2n
已升级到1.1彩色版,请及时下载最新版使用,更新修复了旧版的7个错误,代码共计更新50处。

作者: freesoft00    时间: 2017-2-25 20:34

回复 5# happy886rr


    涉及到这样处理的注册表一般都是做系统或者做winpe的时候,不涉及到系统能不能启动。而且这样的操作,纯入门的电脑使用者一般不会去操作。涉及不到安全性问题。
作者: happy886rr    时间: 2017-2-25 20:46

回复 7# freesoft00
好的,建议已经采纳,你先打个草稿,把希望的功能和它的开关名都告诉我,然后我很快就能实现。要不然,我不知道做成什么样才是你需要的。
作者: freesoft00    时间: 2017-2-26 09:39

回复 8# happy886rr


    /t       指定注册表值数据类型。
         有效的值是:
           REG_SZ, REG_MULTI_SZ, REG_EXPAND_SZ,
           REG_DWORD, REG_QWORD, REG_BINARY, REG_NONE
         默认为所有类型。

/c       指定搜索时区分大小写。
         默认搜索为不区分大小写。

/k       指定只在项名称中搜索。

/d       指定只在数据中搜索。

/s       循环查询所有子项和值

/r       替换的数值
         例如:"AGroup" -r "BGroup" //AGroup替换为BGroup
               "AGroup" -r "" //AGroup替换为空,相当于删除AGroup内容
               "*AGroup?" -r "BGroupw" //支持*、?通配符

/p       指定要搜索的注册表位置
         例如:"AGroup" -r "BGroup" -p "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft"
              //只把HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft该子键下的AGroup替换成BGroup

/re      支持正则搜索替换


我也不太懂,看是否合适
作者: happy886rr    时间: 2017-2-26 11:22

本帖最后由 happy886rr 于 2017-2-26 12:30 编辑

回复 9# freesoft00
好的,开关已经采纳,目前可用的API函数有,这个项目比较复杂,我需要构思几天。
  1. RegCloseKey  
  2. RegConnectRegistry  
  3. RegCreateKey  
  4. RegCreateKeyEx  
  5. RegDeleteKey  
  6. RegDeleteValue  
  7. RegEnumKey  
  8. RegEnumKeyEx  
  9. RegEnumValue  
  10. RegFlushKey  
  11. RegGetKeySecurity  
  12. RegLoadKey  
  13. RegNotifyChangeKeyValue  
  14. RegOpenKey  
  15. RegOpenKeyEx  
  16. RegQueryInfoKey  
  17. RegQueryMultipleValues  
  18. RegQueryValue  
  19. RegQueryValueEx  
  20. RegReplaceKey  
  21. RegRestoreKey  
  22. RegSaveKey  
  23. RegSetKeySecurity  
  24. RegSetValue  
  25. RegSetValueEx  
  26. RegUnLoadKey
复制代码

作者: aries215    时间: 2023-2-24 00:54

本帖最后由 aries215 于 2023-2-24 01:01 编辑

回复 9# freesoft00
已有rxrepl,附件在无忧论坛,支持PCRE正则和Unicode,以下特点尤其适合处理注册表文件:
        Advanced Options:
          -m [ --mode ] arg     Matching mode (line,file)
          --eol arg             End of line sequence.
          -e [ --encoding ] arg Input file encoding (ansi,utf8,utf16le,utf16be,auto)
          --output-encoding arg Output file encoding (ansi,utf8,utf16le,utf16be,auto)
          --no-backup           Supress backup of input file
          --no-bom              Do not write unicode byte order mask (BOM)
          --return-count        Return the number of replacements made
          --options arg         Options file





欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2