找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 32986|回复: 20

正则文本查找工具rf.exe

[复制链接]
发表于 2016-11-6 00:50:32 | 显示全部楼层 |阅读模式
本帖最后由 happy886rr 于 2016-12-5 22:48 编辑

[2016/11/30]修复了ansi编码下/G:开关的漏洞,不作版本号提升,不作重新编译,只在核心源码中作了更新。

RF.EXE
-----------------------------------------------------------------------------
取代find、findstr的正则查找工具,智能识别文本编码,自动判断BOM类型。原生支持
ANSI、UTF8、Unicode、Unicode big endian编码。准确识别有无BOM类型。

支持pcre正则表达式查找、精确字符串查找,多种开关,完全模仿微软findstr的开关及
使用方法。具体用法与findstr大同小异,请自行品味。

源码完全开放,gcc、tcc均可编译。VC稍加修改亦能通过。
-----------------------------------------------------------------------------
COPYRIGHT@2016~2018 BY HAPPY, VERSION 1.0
REGEX FIND TOOLS
-----------------------------------------------------------------------------
rf [/F|/N|/V] [/S:[match string]     ]|
              [/R:[pcre expression]  ]|
              [/G:[ANSI strings file]] [txtfile]
-----------------------------------------------------------------------------
   /H  Show help information
   /F  Finds the line to which matches
   /N  Print the line number
   /V  Shows all rows that do not contain matching regulars
   /S: Finds the line to which the string matches
   /R: Finds the line to which the regular expression matches
   /G: Gets the matching strings from a ANSI strings file
-----------------------------------------------------------------------------
                                                                   11/06/2016

图片存为a.zip解压即是


核心代码:
  1. /*
  2.         REGEX FIND TOOLS, VERSION 1.0
  3.         RF.EXE
  4.         COPYRIGHT@2016~2018 BY HAPPY
  5. */
  6. //静态编译(pcre)
  7. #define PCRE_STATIC
  8. #include    "pcre.h"
  9. #include   <stdio.h>
  10. #include  <string.h>
  11. #include  <locale.h>
  12. #include <stdbool.h>
  13. #include <windows.h>

  14. //定义行长(字节)
  15. #define BUFF_SIZE 4096
  16. //检测阈值(字节)
  17. #define CHECK_SIZE 16383

  18. //基础函数群
  19. char* UnicodeToANSI(const wchar_t* Str)
  20. {
  21.         int L=WideCharToMultiByte(CP_ACP, 0, Str, -1, NULL, 0, NULL, NULL);
  22.         char* Out=(char *)calloc(L+1, sizeof(char));
  23.         WideCharToMultiByte(CP_ACP, 0, Str, -1, Out, L, NULL, NULL);
  24.         return Out;
  25. }
  26. wchar_t* UTF8ToUnicode(const char* Str)
  27. {
  28.         int L=MultiByteToWideChar(CP_UTF8, 0, Str,-1, NULL, 0);
  29.         wchar_t* Out=(wchar_t *)calloc(L+1, sizeof(wchar_t));
  30.         MultiByteToWideChar(CP_UTF8, 0, Str, -1, (LPWSTR)Out, L);
  31.         return Out;
  32. }
  33. bool isUTF8(const char* Str)
  34. {
  35.         if(!Str){
  36.                 return false;
  37.         }
  38.         const unsigned char* bytes=(const unsigned char *)Str;
  39.         while(*bytes){
  40.                 if(
  41.                         (
  42.                                  bytes[0]<=0x7F ||
  43.                                 bytes[0]==0x09 ||
  44.                                 bytes[0]==0x0A ||
  45.                                 bytes[0]==0x0D ||
  46.                                 (0x20<=bytes[0] && bytes[0]<=0x7E)
  47.                         )
  48.                 ){
  49.                         bytes+=1;
  50.                         continue;
  51.                 }
  52.                 if(
  53.                          (
  54.                                 (0xC2<=bytes[0] && bytes[0]<=0xDF) &&
  55.                                 (0x80<=bytes[1] && bytes[1]<=0xBF)
  56.                         )
  57.                 ){
  58.                         bytes+=2;
  59.                         continue;
  60.                 }
  61.                 if(
  62.                         (
  63.                                                   (bytes[0]==0xE0) &&
  64.                                 (0xA0<=bytes[1] && bytes[1]<=0xBF) &&
  65.                                 (0x80<=bytes[2] && bytes[2]<=0xBF)
  66.                         ) ||
  67.                         (
  68.                                 (
  69.                                         (0xE1<=bytes[0] && bytes[0]<=0xEC)||
  70.                                                            bytes[0]==0xEE ||
  71.                                                            bytes[0]==0xEF
  72.                                                                  ) &&
  73.                                 (0x80<=bytes[1] && bytes[1]<=0xBF) &&
  74.                                 (0x80<=bytes[2] && bytes[2]<=0xBF)
  75.                         ) ||
  76.                         (
  77.                                                   (bytes[0]==0xED) &&
  78.                                 (0x80<=bytes[1] && bytes[1]<=0x9F) &&
  79.                                 (0x80<=bytes[2] && bytes[2]<=0xBF)
  80.                         )
  81.                 ){
  82.                         bytes+=3;
  83.                         continue;
  84.                 }
  85.                 if(
  86.                         (
  87.                                                   (bytes[0]==0xF0) &&
  88.                                 (0x90<=bytes[1] && bytes[1]<=0xBF) &&
  89.                                 (0x80<=bytes[2] && bytes[2]<=0xBF) &&
  90.                                 (0x80<=bytes[3] && bytes[3]<=0xBF)
  91.                         ) ||
  92.                         (
  93.                                 (0xF1<=bytes[0] && bytes[0]<=0xF3) &&
  94.                                 (0x80<=bytes[1] && bytes[1]<=0xBF) &&
  95.                                 (0x80<=bytes[2] && bytes[2]<=0xBF) &&
  96.                                 (0x80<=bytes[3] && bytes[3]<=0xBF)
  97.                         ) ||
  98.                         (
  99.                                                   (bytes[0]==0xF4) &&
  100.                                 (0x80<=bytes[1] && bytes[1]<=0x8F) &&
  101.                                 (0x80<=bytes[2] && bytes[2]<=0xBF) &&
  102.                                 (0x80<=bytes[3] && bytes[3]<=0xBF)
  103.                         )
  104.                 ){
  105.                         bytes+=4;
  106.                         continue;
  107.                 }
  108.                 return false;
  109.         }
  110.         return true;
  111. }

  112. //BOM检测
  113. int CheckBom(FILE* fp)
  114. {
  115.         unsigned char* buf=(unsigned char*)calloc(3,sizeof(unsigned char));
  116.         unsigned char* buf2;
  117.         fseek(fp, 0, SEEK_SET);
  118.         fread(buf, sizeof(unsigned char), 3, fp);
  119.              if(buf[0]==0xEF && buf[1]==0xBB && buf[2]==0xBF){return 3;}
  120.         else if(buf[0]==0xFF && buf[1]==0xFE){return 5;}
  121.         else if(buf[0]==0xFE && buf[1]==0xFF){return 6;}
  122.         else{
  123.                 fseek(fp, 0, SEEK_SET);
  124.                 buf2=(unsigned char*)calloc(CHECK_SIZE,sizeof(unsigned char));
  125.                 fread(buf2, sizeof(unsigned char), CHECK_SIZE, fp);
  126.                 if(isUTF8(buf2)){
  127.                         free(buf2);
  128.                         return 2;
  129.                 }
  130.                 free(buf2);
  131.         }
  132.         return 1;
  133. }

  134. //正则查找函数
  135. int RFindLine(FILE* fp, char* src, int FLAG)
  136. {
  137.         bool mode=false;
  138.         int BOM=0, EN=0, i=0, n=0;
  139.         FILE* sp;
  140.         char* Li=(char *)malloc(BUFF_SIZE*sizeof(char));
  141.         char* LineV;char* LineU;
  142.         pcre  *re;
  143.         int erroffset, ovector[30], rc;
  144.         const char *error;

  145.         if      ( (FLAG&0x0F)==0x02 ){
  146.                 pcre_compile(src, 0, &error, &erroffset, NULL);
  147.                 if( (re=pcre_compile(src, 0, &error, &erroffset, NULL)) == NULL ){
  148.                         fputs("PCRE compilation failed", stderr);
  149.                         exit(1);
  150.                 }
  151.         }else if( (FLAG&0x0F)==0x03 ){
  152.                 if( (sp=fopen(src, "rb"))==NULL ){
  153.                         fputs("Read matching failed", stderr);
  154.                         exit(1);
  155.                 }       
  156.         }
  157.         //BOM偏移值
  158.         BOM=CheckBom(fp);
  159.         if      (BOM==1 || BOM==2){
  160.                 EN=0;
  161.         }else if(BOM==5 || BOM==6){
  162.                 EN=2;
  163.         }else if(BOM==3){
  164.                 EN=3;
  165.         }
  166.         //执行偏移值
  167.         fseek(fp, EN, SEEK_SET);
  168.         //执行匹配过程
  169.         if(BOM==1){
  170.                 char* Line=(char *)malloc(BUFF_SIZE*sizeof(char));
  171.                 while(!feof(fp)){
  172.                         memset(Line, 0, BUFF_SIZE*sizeof(char));
  173.                         fgets(Line, BUFF_SIZE, fp);
  174.                         i++;
  175.                         if      ( (FLAG&0x0F)==0x01 ){
  176.                                 if( strstr(Line, src)!=NULL ){
  177.                                         mode=true;
  178.                                 }else{
  179.                                         mode=false;
  180.                                 }
  181.                         }else if( (FLAG&0x0F)==0x02 ){
  182.                                 if( pcre_exec(re, NULL, Line, strlen(Line), 0, 0, ovector, 30) >= 0 ){
  183.                                         mode=true;
  184.                                 }else{
  185.                                         mode=false;
  186.                                 }
  187.                         }else if( (FLAG&0x0F)==0x03 ){
  188.                                 mode=false;
  189.                                 fseek(sp, 0, SEEK_SET);
  190.                                 while(!feof(sp)){
  191.                                         memset(Li, 0, BUFF_SIZE*sizeof(char));
  192.                                         fgets(Li, BUFF_SIZE, sp);
  193.                                         char* tp=Li;
  194.                                         while(*tp=='\t' ||*tp==' ' ||*tp=='\r' ||*tp=='\n'){tp++;}
  195.                                         int tp_LEN=strlen(tp);
  196.                                         tp[tp_LEN-2]=(tp[tp_LEN-2]=='\r')?'\0':tp[tp_LEN-2];
  197.                                         if(tp[0]!='\0' &&strstr(Line, tp)!=NULL){
  198.                                                 mode=true;
  199.                                                 break;
  200.                                         }
  201.                                 }
  202.                         }
  203.                         //输出显示
  204.                         if( (FLAG>>4)==0x03 && mode==true ){
  205.                                         fprintf(stdout, "%d:%s", i, Line);
  206.                         }else if(
  207.                                         ((FLAG>>4)==0x02 && mode==false)||
  208.                                         ((FLAG>>4)==0x01 && mode==true )
  209.                         ){
  210.                                 fputs(Line, stdout);
  211.                         }
  212.                 }
  213.         }else if(BOM==2 || BOM==3){
  214.                 char* Line=(char *)malloc(BUFF_SIZE*sizeof(char));
  215.                 while(!feof(fp)){
  216.                         memset(Line, 0, BUFF_SIZE*sizeof(char));
  217.                         fgets(Line, BUFF_SIZE, fp);
  218.                         i++;
  219.                         if(BOM>1){LineU=UnicodeToANSI(UTF8ToUnicode(Line));}
  220.                         if      ( (FLAG&0x0F)==0x01 ){
  221.                                 if( strstr(LineU, src)!=NULL ){
  222.                                         mode=true;
  223.                                 }else{
  224.                                         mode=false;
  225.                                 }
  226.                         }else if( (FLAG&0x0F)==0x02 ){
  227.                                 if( pcre_exec(re, NULL, LineU, strlen(LineU), 0, 0, ovector, 30) >= 0 ){
  228.                                         mode=true;
  229.                                 }else{
  230.                                         mode=false;
  231.                                 }
  232.                         }else if( (FLAG&0x0F)==0x03 ){
  233.                                 fseek(sp, 0, SEEK_SET);
  234.                                 while(!feof(sp)){
  235.                                         memset(Li, 0, BUFF_SIZE*sizeof(char));
  236.                                         fgets(Li, BUFF_SIZE, sp);
  237.                                         if( strstr(LineU, Li)!=NULL ){
  238.                                                 mode=true;
  239.                                                 break;
  240.                                         }
  241.                                 }
  242.                         }
  243.                         //输出显示
  244.                         if( (FLAG>>4)==0x03 && mode==true ){
  245.                                         fprintf(stdout, "%d:%s", i, LineU);
  246.                         }else if(
  247.                                         ((FLAG>>4)==0x02 && mode==false)||
  248.                                         ((FLAG>>4)==0x01 && mode==true )
  249.                         ){
  250.                                 fputs(LineU, stdout);
  251.                         }
  252.                 }
  253.         }else if(BOM==5){               //Unicode
  254.                 wchar_t* LineW=(wchar_t *)calloc(BUFF_SIZE, sizeof(wchar_t));
  255.                 while(!feof(fp)){
  256.                         memset(LineW, 0, BUFF_SIZE*sizeof(wchar_t));
  257.                         fgetws(LineW, BUFF_SIZE, fp);
  258.                         i++;
  259.                         LineV=UnicodeToANSI(LineW);
  260.                         if      ( (FLAG&0x0F)==0x01 ){
  261.                                 if( strstr(LineV, src)!=NULL ){
  262.                                         mode=true;
  263.                                 }else{
  264.                                         mode=false;
  265.                                 }
  266.                         }else if( (FLAG&0x0F)==0x02 ){
  267.                                 if( pcre_exec(re, NULL, LineV, strlen(LineV), 0, 0, ovector, 30) >= 0 ){
  268.                                         mode=true;
  269.                                 }else{
  270.                                         mode=false;
  271.                                 }
  272.                         }else if( (FLAG&0x0F)==0x03 ){
  273.                                 fseek(sp, 0, SEEK_SET);
  274.                                 while(!feof(sp)){
  275.                                         memset(Li, 0, BUFF_SIZE*sizeof(char));
  276.                                         fgets(Li, BUFF_SIZE, sp);
  277.                                         if( strstr(LineV, Li)!=NULL ){
  278.                                                 mode=true;
  279.                                                 break;
  280.                                         }
  281.                                 }
  282.                         }
  283.                         if      ( (FLAG>>4)==0x03 && mode==true ){
  284.                                 fprintf(stdout, "%d:%s", i, LineV);
  285.                         }else if(
  286.                                         ((FLAG>>4)==0x02 && mode==false)||
  287.                                         ((FLAG>>4)==0x01 && mode==true )
  288.                         ){
  289.                                 fputs(LineV, stdout);
  290.                         }
  291.                 }
  292.         }else if(BOM==6){               //Unicode big endian
  293.                 wchar_t* LineW=(wchar_t *)calloc(BUFF_SIZE, sizeof(wchar_t));
  294.                 while(!feof(fp)){
  295.                         memset(LineW, 0, BUFF_SIZE*sizeof(wchar_t));
  296.                         fgets(LineW, BUFF_SIZE, fp);
  297.                         i++;
  298.                         for(n=0;LineW[n]!=0x0000;n++){
  299.                                 LineW[n]=(LineW[n]&0x00FF)<<8|(LineW[n]&0xFF00)>>8;
  300.                         }
  301.                         LineV=UnicodeToANSI(LineW);
  302.                         if      ( (FLAG&0x0F)==0x01 ){
  303.                                 if( strstr(LineV, src)!=NULL ){
  304.                                         mode=true;
  305.                                 }else{
  306.                                         mode=false;
  307.                                 }
  308.                         }else if( (FLAG&0x0F)==0x02 ){
  309.                                 if( pcre_exec(re, NULL, LineV, strlen(LineV), 0, 0, ovector, 30) >= 0 ){
  310.                                         mode=true;
  311.                                 }else{
  312.                                         mode=false;
  313.                                 }
  314.                         }else if( (FLAG&0x0F)==0x03 ){
  315.                                 fseek(sp, 0, SEEK_SET);
  316.                                 while(!feof(sp)){
  317.                                         memset(Li, 0, BUFF_SIZE*sizeof(char));
  318.                                         fgets(Li, BUFF_SIZE, sp);
  319.                                         if( strstr(LineV, Li)!=NULL ){
  320.                                                 mode=true;
  321.                                                 break;
  322.                                         }
  323.                                 }
  324.                         }
  325.                         if      ( (FLAG>>4)==0x03 && mode==true ){
  326.                                 fprintf(stdout, "%d:%s", i, LineV);
  327.                         }else if(
  328.                                         ((FLAG>>4)==0x02 && mode==false)||
  329.                                         ((FLAG>>4)==0x01 && mode==true )
  330.                         ){
  331.                                 fputs(LineV, stdout);
  332.                         }
  333.                 }
  334.         }
  335.         fflush(stdout);
  336.         if( (FLAG&0x0F)==0x02 ){pcre_free(re);}
  337.         free(Li);
  338.         return 0;
  339. }

  340. //帮助信息
  341. void Help_Info(FILE* stream, int Exit_Code)
  342. {
  343.         fprintf(stream,
  344.                 "COPYRIGHT@2016~2018 BY HAPPY, VERSION 1.0\n"
  345.                 "REGEX FIND TOOLS\n"
  346.                 "-----------------------------------------------------------------------------\n"
  347.                 "rf [/F|/N|/V] [/S:[match string]     ]|\n"
  348.                 "              [/R:[pcre expression]  ]|\n"
  349.                 "              [/G:[ANSI strings file]] [txtfile]\n"
  350.                 "-----------------------------------------------------------------------------\n"
  351.                 "   /H  Show help information\n"
  352.                 "   /F  Finds the line to which matches\n"
  353.                 "   /N  Print the line number\n"
  354.                 "   /V  Shows all rows that do not contain matching regulars\n"
  355.                 "   /S: Finds the line to which the string matches\n"
  356.                 "   /R: Finds the line to which the regular expression matches\n"
  357.                 "   /G: Gets the matching strings from a ANSI strings file\n"
  358.                 "-----------------------------------------------------------------------------\n"
  359.                 "                                                                   11/06/2016\n"
  360.         );
  361.         exit(Exit_Code);
  362. }

  363. //主函数入口
  364. int main(int argc, char** argv)
  365. {
  366.         FILE* fp;
  367.         unsigned char FLAG=0;
  368.         if( (argc==4) && (argv[1][0]=='/') && (argv[2][0]=='/') && (argv[2][2]== ':') ){
  369.                 switch(argv[1][1]){
  370.                         case 'F':
  371.                         case 'f':
  372.                                 FLAG|=0x10;
  373.                                 break;
  374.                         case 'V':
  375.                         case 'v':
  376.                                 FLAG|=0x20;
  377.                                 break;
  378.                         case 'N':
  379.                         case 'n':
  380.                                 FLAG|=0x30;
  381.                                 break;
  382.                         default:
  383.                                 Help_Info(stderr, 2);
  384.                 }
  385.                 switch(argv[2][1]){
  386.                         case 'S':
  387.                         case 's':
  388.                                 FLAG|=0x01;
  389.                                 break;
  390.                         case 'R':
  391.                         case 'r':
  392.                                 FLAG|=0x02;
  393.                                 break;
  394.                         case 'G':
  395.                         case 'g':
  396.                                 FLAG|=0x03;
  397.                                 break;
  398.                         default:
  399.                                 Help_Info(stderr, 1);
  400.                 }
  401.         }else {
  402.                 Help_Info(stderr, 3);
  403.         }

  404.         if( (fp=fopen(argv[3], "rb"))==NULL ){
  405.                 fputs("Read failed", stderr);
  406.                 return 3;
  407.         }
  408.         RFindLine(fp, argv[2]+3, FLAG);
  409.         fclose(fp);
  410.         return 0;
  411. }
复制代码

评分

参与人数 1技术 +1 收起 理由
freesoft00 + 1 +1

查看全部评分

发表于 2016-11-6 01:10:53 | 显示全部楼层
又在重复造轮子, 缩进不要超过3层
发表于 2016-11-6 02:43:30 | 显示全部楼层
回复 2# Bella


    别人的造的轮子是别人的。自己造的轮子才是自己的。
发表于 2016-11-6 03:23:53 | 显示全部楼层
求教,如何把字符串 “D:\My Documents\Pictures\★★★2016113-154wer52.jpg" 中的文件名用正则表达式提取出来?

我想得到的字符串是这个 “★★2016113-154wer52.jpg”  (注意:文件名少一个 ★ 号)。

正则测试工具用  (?<=★).*  是行的。但不知RF怎么写。
发表于 2016-11-6 07:27:18 | 显示全部楼层
好东西好东西好东西
 楼主| 发表于 2016-11-6 09:34:33 | 显示全部楼层
回复 4# sanmaodo
容易,在rf源码的227行下面添加如下代码。编译成exe即可提取子串。
  1. for (int i = 0; i < pcre_exec(re, NULL, Line, strlen(Line), 0, 0, ovector, 30); i++) {
  2.         char *getkeywords = src + ovector[2*i];
  3.         printf("%s\n",getkeywords);
  4. }
复制代码
rf使用pcre正则,因此,你的正则式  (?<=★).*无需更改,直接使用。
rf暂时不开放其他特殊功能,这个模块请自行添加用gcc或tcc编译即可。

评分

参与人数 1技术 +1 收起 理由
sanmaodo + 1 谢谢!

查看全部评分

发表于 2016-11-6 12:36:05 | 显示全部楼层
回复 6# happy886rr
非常感谢!
发表于 2016-12-1 13:12:42 | 显示全部楼层
gcc需要在linux中编译,还是可以在windows的gcc就可以?
 楼主| 发表于 2016-12-1 13:36:03 | 显示全部楼层
回复 8# freesoft00
那个图片存为zip格式,必须用winrar软件才能解压,压缩包里有exe文件,不用编译,要编译也只支持windows下的gcc编译。
发表于 2016-12-1 15:09:00 | 显示全部楼层
回复 9# happy886rr


    压缩包里有exe文件

exe不是最新版本呀。
发表于 2016-12-1 15:11:32 | 显示全部楼层
本帖最后由 523066680 于 2016-12-1 15:25 编辑

回复 10# freesoft00


有这一句   #include <windows.h>
当然是 windows

话说没去试就问问题也是服了 。。。

我觉得楼主可以开一个网盘专门分享附件。图片另存-改扩展名-解压 其实也不太方便。
 楼主| 发表于 2016-12-1 16:20:42 | 显示全部楼层
回复 11# 523066680
很好的建议,我之前的好多图片都是外链,那些图片网站只保存半个月,就让我的图片失效了。下回直接整百度网盘吧。
 楼主| 发表于 2016-12-1 16:30:34 | 显示全部楼层
回复 10# freesoft00
也对,编译参数是
  1. gcc RF.c -lpcre -L./ -oRF.exe
复制代码
windows下最好用mingw32编译器。使用-O3优化以达到最佳编译效果。后续我将会去开发linux的第三方,之后的第三方我将尽量提供双平台版本以及安卓手机版。

评分

参与人数 1技术 +1 收起 理由
freesoft00 + 1 +1

查看全部评分

发表于 2016-12-1 18:53:49 | 显示全部楼层
回复 13# happy886rr

https://sourceforge.net/projects/mingw/files/?source=navbar
https://sourceforge.net/projects/mingw-w64/files/?source=navbar
这两个是哪一个。不好意思,对这个不熟悉,所以问的问题比较初级。
发表于 2016-12-1 19:00:50 | 显示全部楼层
本帖最后由 523066680 于 2016-12-1 19:03 编辑

回复 14# freesoft00


    https://nuwen.net/mingw.html

二选一
mingw-14.0.exe
mingw-14.0-without-git.exe

评分

参与人数 1技术 +1 收起 理由
freesoft00 + 1 +1

查看全部评分

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-17 00:39 , Processed in 0.026637 second(s), 9 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表